From: Peter Korsgaard Date: Thu, 9 Jun 2011 08:18:05 +0000 (+0200) Subject: uClibc: bump 0.9.31.x version X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3eb9a36aa351ed8a5cc93665985fed2824e1efe5;p=buildroot.git uClibc: bump 0.9.31.x version Signed-off-by: Peter Korsgaard --- diff --git a/toolchain/uClibc/Config.in b/toolchain/uClibc/Config.in index c264ba282c..36b18a7569 100644 --- a/toolchain/uClibc/Config.in +++ b/toolchain/uClibc/Config.in @@ -39,7 +39,7 @@ config BR2_UCLIBC_VERSION_STRING string default 0.9.29 if BR2_UCLIBC_VERSION_0_9_29 default 0.9.30.3 if BR2_UCLIBC_VERSION_0_9_30 - default 0.9.31 if BR2_UCLIBC_VERSION_0_9_31 + default 0.9.31.1 if BR2_UCLIBC_VERSION_0_9_31 default 0.9.32-rc3 if BR2_UCLIBC_VERSION_0_9_32 default $BR2_USE_UCLIBC_SNAPSHOT if BR2_UCLIBC_VERSION_SNAPSHOT diff --git a/toolchain/uClibc/uClibc-0.9.31-add-bsd-endian-conversions.patch b/toolchain/uClibc/uClibc-0.9.31-add-bsd-endian-conversions.patch deleted file mode 100644 index 652d7c9f10..0000000000 --- a/toolchain/uClibc/uClibc-0.9.31-add-bsd-endian-conversions.patch +++ /dev/null @@ -1,64 +0,0 @@ -From c6d6237819037168a6923ac080e348e54615422c Mon Sep 17 00:00:00 2001 -From: Vladimir Zapolskiy -Date: Tue, 1 Jun 2010 23:22:57 +0400 -Subject: [PATCH] endian.h: add BSD convertions between big/little-endian byte order - -This patch adds support for convertion of values between host and -big-/little-endian byte order. - -Signed-off-by: Vladimir Zapolskiy -Signed-off-by: Bernhard Reutner-Fischer ---- - include/endian.h | 38 ++++++++++++++++++++++++++++++++++++++ - 1 files changed, 38 insertions(+), 0 deletions(-) - -diff --git a/include/endian.h b/include/endian.h -index 2f7bce1..0ba7384 100644 ---- a/include/endian.h -+++ b/include/endian.h -@@ -55,4 +55,42 @@ - # define __LONG_LONG_PAIR(HI, LO) HI, LO - #endif - -+ -+#ifdef __USE_BSD -+/* Conversion interfaces. */ -+# include -+ -+# if __BYTE_ORDER == __LITTLE_ENDIAN -+# define htobe16(x) __bswap_16 (x) -+# define htole16(x) (x) -+# define be16toh(x) __bswap_16 (x) -+# define le16toh(x) (x) -+ -+# define htobe32(x) __bswap_32 (x) -+# define htole32(x) (x) -+# define be32toh(x) __bswap_32 (x) -+# define le32toh(x) (x) -+ -+# define htobe64(x) __bswap_64 (x) -+# define htole64(x) (x) -+# define be64toh(x) __bswap_64 (x) -+# define le64toh(x) (x) -+# else -+# define htobe16(x) (x) -+# define htole16(x) __bswap_16 (x) -+# define be16toh(x) (x) -+# define le16toh(x) __bswap_16 (x) -+ -+# define htobe32(x) (x) -+# define htole32(x) __bswap_32 (x) -+# define be32toh(x) (x) -+# define le32toh(x) __bswap_32 (x) -+ -+# define htobe64(x) (x) -+# define htole64(x) __bswap_64 (x) -+# define be64toh(x) (x) -+# define le64toh(x) __bswap_64 (x) -+# endif -+#endif -+ - #endif /* endian.h */ --- -1.7.3.4 - diff --git a/toolchain/uClibc/uClibc-0.9.31-add-inotify-init1.patch b/toolchain/uClibc/uClibc-0.9.31-add-inotify-init1.patch deleted file mode 100644 index cbec426238..0000000000 --- a/toolchain/uClibc/uClibc-0.9.31-add-inotify-init1.patch +++ /dev/null @@ -1,64 +0,0 @@ -From a2e5630af426f85fdd8721b2820786d9bd2aa695 Mon Sep 17 00:00:00 2001 -From: Vladimir Zapolskiy -Date: Tue, 1 Jun 2010 20:02:54 +0400 -Subject: [PATCH] inotify: add inotify_init1 system call support - -This patch introduces support for inotify_init1 system call, found -since Linux 2.6.27. - -Signed-off-by: Vladimir Zapolskiy -Signed-off-by: Khem Raj ---- - libc/sysdeps/linux/common/inotify.c | 4 ++++ - libc/sysdeps/linux/common/sys/inotify.h | 13 +++++++++++++ - 2 files changed, 17 insertions(+), 0 deletions(-) - -diff --git a/libc/sysdeps/linux/common/inotify.c b/libc/sysdeps/linux/common/inotify.c -index e5a6120..e35f043 100644 ---- a/libc/sysdeps/linux/common/inotify.c -+++ b/libc/sysdeps/linux/common/inotify.c -@@ -15,6 +15,10 @@ - _syscall0(int, inotify_init) - #endif - -+#ifdef __NR_inotify_init1 -+_syscall1(int, inotify_init1, int, flags) -+#endif -+ - #ifdef __NR_inotify_add_watch - _syscall3(int, inotify_add_watch, int, fd, const char *, path, uint32_t, mask) - #endif -diff --git a/libc/sysdeps/linux/common/sys/inotify.h b/libc/sysdeps/linux/common/sys/inotify.h -index 0131db9..dc4e19d 100644 ---- a/libc/sysdeps/linux/common/sys/inotify.h -+++ b/libc/sysdeps/linux/common/sys/inotify.h -@@ -22,6 +22,16 @@ - #include - - -+/* Flags for the parameter of inotify_init1. */ -+enum -+ { -+ IN_CLOEXEC = 02000000, -+#define IN_CLOEXEC IN_CLOEXEC -+ IN_NONBLOCK = 04000 -+#define IN_NONBLOCK IN_NONBLOCK -+ }; -+ -+ - /* Structure describing an inotify event. */ - struct inotify_event - { -@@ -79,6 +89,9 @@ __BEGIN_DECLS - /* Create and initialize inotify instance. */ - extern int inotify_init (void) __THROW; - -+/* Create and initialize inotify instance. */ -+extern int inotify_init1 (int __flags) __THROW; -+ - /* Add watch of object NAME to inotify instance FD. Notify about - events specified by MASK. */ - extern int inotify_add_watch (int __fd, const char *__name, uint32_t __mask) --- -1.7.3.4 - diff --git a/toolchain/uClibc/uClibc-0.9.31-add-sock-cloexec.patch b/toolchain/uClibc/uClibc-0.9.31-add-sock-cloexec.patch deleted file mode 100644 index a7089a98ac..0000000000 --- a/toolchain/uClibc/uClibc-0.9.31-add-sock-cloexec.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 83333e9c873e4eca6b2c945f7770b1f5373b0427 Mon Sep 17 00:00:00 2001 -From: Vladimir Zapolskiy -Date: Tue, 1 Jun 2010 20:02:39 +0400 -Subject: [PATCH] bits/socket.h: add SOCK_CLOEXEC and SOCK_NONBLOCK support - -This patch adds support for SOCK_CLOEXEC and SOCK_NONBLOCK socket -descriptor flags, which are introduced since Linux 2.6.27 - -Signed-off-by: Vladimir Zapolskiy -Signed-off-by: Khem Raj ---- - libc/sysdeps/linux/common/bits/socket.h | 12 +++++++++++- - 1 files changed, 11 insertions(+), 1 deletions(-) - -diff --git a/libc/sysdeps/linux/common/bits/socket.h b/libc/sysdeps/linux/common/bits/socket.h -index ac5a433..11f6e97 100644 ---- a/libc/sysdeps/linux/common/bits/socket.h -+++ b/libc/sysdeps/linux/common/bits/socket.h -@@ -53,10 +53,20 @@ enum __socket_type - SOCK_SEQPACKET = 5, /* Sequenced, reliable, connection-based, - datagrams of fixed maximum length. */ - #define SOCK_SEQPACKET SOCK_SEQPACKET -- SOCK_PACKET = 10 /* Linux specific way of getting packets -+ SOCK_PACKET = 10, /* Linux specific way of getting packets - at the dev level. For writing rarp and - other similar things on the user level. */ - #define SOCK_PACKET SOCK_PACKET -+ -+ /* Flags to be ORed into the type parameter of socket and socketpair and -+ used for the flags parameter of paccept. */ -+ -+ SOCK_CLOEXEC = 02000000, /* Atomically set close-on-exec flag for the -+ new descriptor(s). */ -+#define SOCK_CLOEXEC SOCK_CLOEXEC -+ SOCK_NONBLOCK = 04000 /* Atomically mark descriptor(s) as -+ non-blocking. */ -+#define SOCK_NONBLOCK SOCK_NONBLOCK - }; - - /* Protocol families. */ --- -1.7.3.4 - diff --git a/toolchain/uClibc/uClibc-0.9.31-dnslookup-use-after-free.patch b/toolchain/uClibc/uClibc-0.9.31-dnslookup-use-after-free.patch deleted file mode 100644 index 9956d591a0..0000000000 --- a/toolchain/uClibc/uClibc-0.9.31-dnslookup-use-after-free.patch +++ /dev/null @@ -1,36 +0,0 @@ -From eb1d8c8289f466ba3ad10b9a88ab2e426b8a9dc7 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Tue, 6 Apr 2010 09:55:19 +0200 -Subject: [PATCH] Fix use-after-free bug in __dns_lookup - -If the type of the first answer does not match with the requested type, -then the dotted name was freed. If there are no further answers in -the DNS reply, this pointer was used later on in the same function. -Additionally it is passed to the caller, and caused strange -behaviour. - -Signed-off-by: Gabor Juhos -Signed-off-by: Bernhard Reutner-Fischer ---- - libc/inet/resolv.c | 4 +--- - 1 files changed, 1 insertions(+), 3 deletions(-) - -diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c -index 056539f..9459199 100644 ---- a/libc/inet/resolv.c -+++ b/libc/inet/resolv.c -@@ -1517,10 +1517,8 @@ int attribute_hidden __dns_lookup(const char *name, - memcpy(a, &ma, sizeof(ma)); - if (a->atype != T_SIG && (NULL == a->buf || (type != T_A && type != T_AAAA))) - break; -- if (a->atype != type) { -- free(a->dotted); -+ if (a->atype != type) - continue; -- } - a->add_count = h.ancount - j - 1; - if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen) - break; --- -1.7.0 - diff --git a/toolchain/uClibc/uClibc-0.9.31-fix-error-locale-utf-8.patch b/toolchain/uClibc/uClibc-0.9.31-fix-error-locale-utf-8.patch deleted file mode 100644 index 1305add50a..0000000000 --- a/toolchain/uClibc/uClibc-0.9.31-fix-error-locale-utf-8.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- - extra/locale/gen_wc8bit.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -Index: uClibc-0.9.31/extra/locale/gen_wc8bit.c -=================================================================== ---- uClibc-0.9.31.orig/extra/locale/gen_wc8bit.c -+++ uClibc-0.9.31/extra/locale/gen_wc8bit.c -@@ -120,7 +120,7 @@ - } - - locale_failure: -- printf("could not find a UTF8 locale ... please enable en_US.UTF-8\n"); -+ fprintf(stderr, "could not find a UTF8 locale ... please enable en_US.UTF-8\n"); - return EXIT_FAILURE; - locale_success: - pclose(fp); diff --git a/toolchain/uClibc/uClibc-0.9.31-fix-fcntl64-for-64-bit-targets.patch b/toolchain/uClibc/uClibc-0.9.31-fix-fcntl64-for-64-bit-targets.patch deleted file mode 100644 index 763bfd39d7..0000000000 --- a/toolchain/uClibc/uClibc-0.9.31-fix-fcntl64-for-64-bit-targets.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 6f1daaaf2d94c1e6184add44eda38b0781b88cf0 Mon Sep 17 00:00:00 2001 -From: Rob Landley -Date: Sun, 16 May 2010 21:41:36 +0000 -Subject: Fix fcntl64 for 64 bit targets. - -64 bit targets often don't have a separate fcntl64() system call, because they don't need one. - -Signed-off-by: Rob Landley -Signed-off-by: Austin Foxley ---- -diff --git a/include/fcntl.h b/include/fcntl.h -index e37073f..3cfb25f 100644 ---- a/include/fcntl.h -+++ b/include/fcntl.h -@@ -73,7 +73,7 @@ __BEGIN_DECLS - - This function is a cancellation point and therefore not marked with - __THROW. */ --#ifndef __USE_FILE_OFFSET64 -+#if !defined(__USE_FILE_OFFSET64) || defined(__LP64__) - extern int fcntl (int __fd, int __cmd, ...); - libc_hidden_proto(fcntl) - #else -@@ -83,7 +83,7 @@ extern int __REDIRECT (fcntl, (int __fd, int __cmd, ...), fcntl64); - # define fcntl fcntl64 - # endif - #endif --#ifdef __USE_LARGEFILE64 -+#if defined(__USE_LARGEFILE64) && !defined(__LP64__) - extern int fcntl64 (int __fd, int __cmd, ...); - libc_hidden_proto(fcntl64) - #endif --- -cgit v0.8.2.1 diff --git a/toolchain/uClibc/uClibc-0.9.31-linuxthreads-errno-fix.patch b/toolchain/uClibc/uClibc-0.9.31-linuxthreads-errno-fix.patch deleted file mode 100644 index c49821bde7..0000000000 --- a/toolchain/uClibc/uClibc-0.9.31-linuxthreads-errno-fix.patch +++ /dev/null @@ -1,98 +0,0 @@ -From af8b2d71ce37b9d4d24ddbc755cdea68de02949a Mon Sep 17 00:00:00 2001 -From: Peter Korsgaard -Date: Mon, 5 Jul 2010 14:08:17 +0200 -Subject: [PATCH] don't make __errno_location / __h_errno_location hidden - -Closes #2089 (https://bugs.busybox.net/show_bug.cgi?id=2089) - -__errno_location / __h_errno_location access has to go through the PLT -like malloc/free, so the linuxthread variants gets used instead when -compiling with -pthread. - -Based on http://github.com/mat-c/uClibc/commit/328d392c54aa5dc2b8e7f398a419087de497de2b - -Signed-off-by: Peter Korsgaard ---- - include/netdb.h | 1 - - libc/misc/internals/__errno_location.c | 3 --- - libc/misc/internals/__h_errno_location.c | 1 - - libc/misc/internals/__uClibc_main.c | 2 -- - libc/sysdeps/linux/common/bits/errno.h | 1 - - libc/sysdeps/linux/common/bits/uClibc_errno.h | 3 --- - 6 files changed, 0 insertions(+), 11 deletions(-) - -diff --git a/include/netdb.h b/include/netdb.h -index 9d3807d..ac411ab 100644 ---- a/include/netdb.h -+++ b/include/netdb.h -@@ -59,7 +59,6 @@ __BEGIN_DECLS - - /* Function to get address of global `h_errno' variable. */ - extern int *__h_errno_location (void) __THROW __attribute__ ((__const__)); --libc_hidden_proto(__h_errno_location) - - /* Macros for accessing h_errno from inside libc. */ - #ifdef _LIBC -diff --git a/libc/misc/internals/__errno_location.c b/libc/misc/internals/__errno_location.c -index 487a9c2..0620860 100644 ---- a/libc/misc/internals/__errno_location.c -+++ b/libc/misc/internals/__errno_location.c -@@ -11,6 +11,3 @@ int * weak_const_function __errno_location (void) - { - return &errno; - } --#ifdef IS_IN_libc /* not really need, only to keep in sync w/ libc_hidden_proto */ --libc_hidden_weak(__errno_location) --#endif -diff --git a/libc/misc/internals/__h_errno_location.c b/libc/misc/internals/__h_errno_location.c -index 213d398..235df4e 100644 ---- a/libc/misc/internals/__h_errno_location.c -+++ b/libc/misc/internals/__h_errno_location.c -@@ -10,4 +10,3 @@ int * weak_const_function __h_errno_location (void) - { - return &h_errno; - } --libc_hidden_weak(__h_errno_location) -diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c -index 6e520fa..f4a9ebb 100644 ---- a/libc/misc/internals/__uClibc_main.c -+++ b/libc/misc/internals/__uClibc_main.c -@@ -64,9 +64,7 @@ void internal_function _dl_aux_init (ElfW(auxv_t) *av); - * Prototypes. - */ - extern int *weak_const_function __errno_location(void); --libc_hidden_proto(__errno_location) - extern int *weak_const_function __h_errno_location(void); --libc_hidden_proto(__h_errno_location) - - extern void weak_function _stdio_init(void) attribute_hidden; - #ifdef __UCLIBC_HAS_LOCALE__ -diff --git a/libc/sysdeps/linux/common/bits/errno.h b/libc/sysdeps/linux/common/bits/errno.h -index 0bf6354..de9688a 100644 ---- a/libc/sysdeps/linux/common/bits/errno.h -+++ b/libc/sysdeps/linux/common/bits/errno.h -@@ -43,7 +43,6 @@ - # ifndef __ASSEMBLER__ - /* Function to get address of global `errno' variable. */ - extern int *__errno_location (void) __THROW __attribute__ ((__const__)); --libc_hidden_proto(__errno_location) - - # ifdef __UCLIBC_HAS_THREADS__ - /* When using threads, errno is a per-thread value. */ -diff --git a/libc/sysdeps/linux/common/bits/uClibc_errno.h b/libc/sysdeps/linux/common/bits/uClibc_errno.h -index 9c15618..79eb7e6 100644 ---- a/libc/sysdeps/linux/common/bits/uClibc_errno.h -+++ b/libc/sysdeps/linux/common/bits/uClibc_errno.h -@@ -33,9 +33,6 @@ extern int *__errno_location (void) __THROW __attribute__ ((__const__)) - ; - # if defined __UCLIBC_HAS_THREADS__ - # include --# if defined USE___THREAD && USE___THREAD --libc_hidden_proto(__errno_location) --# endif - # endif - - #endif /* !__ASSEMBLER__ */ --- -1.7.1 - diff --git a/toolchain/uClibc/uClibc-0.9.31-more-workarounds-GCC-PR32219.patch b/toolchain/uClibc/uClibc-0.9.31-more-workarounds-GCC-PR32219.patch deleted file mode 100644 index 9e6953224c..0000000000 --- a/toolchain/uClibc/uClibc-0.9.31-more-workarounds-GCC-PR32219.patch +++ /dev/null @@ -1,40 +0,0 @@ -From aa67771881d65373da448ad5f7a8393f3a1d9469 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Timo=20Ter=C3=A4s?= -Date: Wed, 30 Jun 2010 14:46:37 +0300 -Subject: [PATCH] more workarounds for GCC PR32219 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Commit 2e53dd645d5348f207cec7f8595969dc566c5a55 workarounds GCC -bug when accessing _locale_init and _stdio_init. We need the same -fix for __errno_location and __h_errno_location otherwise we crash -calling null with static and non-threaded builds. - -Signed-off-by: Timo Teräs -Signed-off-by: Bernhard Reutner-Fischer ---- - libc/misc/internals/__uClibc_main.c | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c -index 3f09ad2..58f6643 100644 ---- a/libc/misc/internals/__uClibc_main.c -+++ b/libc/misc/internals/__uClibc_main.c -@@ -447,11 +447,11 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc, - * have resulted in errno being set nonzero, so set it to 0 before - * we call main. - */ -- if (likely(__errno_location!=NULL)) -+ if (likely(not_null_ptr(__errno_location))) - *(__errno_location()) = 0; - - /* Set h_errno to 0 as well */ -- if (likely(__h_errno_location!=NULL)) -+ if (likely(not_null_ptr(__h_errno_location))) - *(__h_errno_location()) = 0; - - #if defined HAVE_CLEANUP_JMP_BUF && defined __UCLIBC_HAS_THREADS_NATIVE__ --- -1.7.1 - diff --git a/toolchain/uClibc/uClibc-0.9.31-powerpc-ptrace-fix.patch b/toolchain/uClibc/uClibc-0.9.31-powerpc-ptrace-fix.patch deleted file mode 100644 index a5ccecaa3f..0000000000 --- a/toolchain/uClibc/uClibc-0.9.31-powerpc-ptrace-fix.patch +++ /dev/null @@ -1,62 +0,0 @@ -[PATCH] powerpc: add PTRACE_EVENT_ defines needed by ltrace - -Equivalent to the common version and kernel headers. - -Signed-off-by: Peter Korsgaard ---- - libc/sysdeps/linux/powerpc/sys/ptrace.h | 41 +++++++++++++++++++++++++++++++- - 1 file changed, 40 insertions(+), 1 deletion(-) - -Index: uClibc-0.9.31/libc/sysdeps/linux/powerpc/sys/ptrace.h -=================================================================== ---- uClibc-0.9.31.orig/libc/sysdeps/linux/powerpc/sys/ptrace.h -+++ uClibc-0.9.31/libc/sysdeps/linux/powerpc/sys/ptrace.h -@@ -79,8 +79,47 @@ enum __ptrace_request - #define PT_DETACH PTRACE_DETACH - - /* Continue and stop at the next (return from) syscall. */ -- PTRACE_SYSCALL = 24 -+ PTRACE_SYSCALL = 24, - #define PT_SYSCALL PTRACE_SYSCALL -+ -+ /* Set ptrace filter options. */ -+ PTRACE_SETOPTIONS = 0x4200, -+#define PT_SETOPTIONS PTRACE_SETOPTIONS -+ -+ /* Get last ptrace message. */ -+ PTRACE_GETEVENTMSG = 0x4201, -+#define PT_GETEVENTMSG PTRACE_GETEVENTMSG -+ -+ /* Get siginfo for process. */ -+ PTRACE_GETSIGINFO = 0x4202, -+#define PT_GETSIGINFO PTRACE_GETSIGINFO -+ -+ /* Set new siginfo for process. */ -+ PTRACE_SETSIGINFO = 0x4203 -+#define PT_SETSIGINFO PTRACE_SETSIGINFO -+}; -+ -+ -+/* Options set using PTRACE_SETOPTIONS. */ -+enum __ptrace_setoptions { -+ PTRACE_O_TRACESYSGOOD = 0x00000001, -+ PTRACE_O_TRACEFORK = 0x00000002, -+ PTRACE_O_TRACEVFORK = 0x00000004, -+ PTRACE_O_TRACECLONE = 0x00000008, -+ PTRACE_O_TRACEEXEC = 0x00000010, -+ PTRACE_O_TRACEVFORKDONE = 0x00000020, -+ PTRACE_O_TRACEEXIT = 0x00000040, -+ PTRACE_O_MASK = 0x0000007f -+}; -+ -+/* Wait extended result codes for the above trace options. */ -+enum __ptrace_eventcodes { -+ PTRACE_EVENT_FORK = 1, -+ PTRACE_EVENT_VFORK = 2, -+ PTRACE_EVENT_CLONE = 3, -+ PTRACE_EVENT_EXEC = 4, -+ PTRACE_EVENT_VFORK_DONE = 5, -+ PTRACE_EVENT_EXIT = 6 - }; - - /* Perform process tracing functions. REQUEST is one of the values diff --git a/toolchain/uClibc/uClibc-0.9.31-quad-routines.patch b/toolchain/uClibc/uClibc-0.9.31-quad-routines.patch deleted file mode 100644 index de37c30370..0000000000 --- a/toolchain/uClibc/uClibc-0.9.31-quad-routines.patch +++ /dev/null @@ -1,7393 +0,0 @@ -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/Makefile.arch uClibc-0.9.31/libc/sysdeps/linux/sparc/Makefile.arch ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/Makefile.arch 2010-10-14 14:03:46.000000000 +0200 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/Makefile.arch 2010-10-14 14:36:34.000000000 +0200 -@@ -5,8 +5,15 @@ - # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. - # - --CSRC := brk.c __syscall_error.c qp_ops.c sigaction.c -+CSRC := brk.c __syscall_error.c sigaction.c - - SSRC := \ - __longjmp.S fork.S vfork.S clone.S setjmp.S bsd-setjmp.S bsd-_setjmp.S \ - syscall.S urem.S udiv.S umul.S sdiv.S rem.S pipe.S -+ -+CSRC += $(foreach f, \ -+ q_div.c q_fle.c q_mul.c q_qtoll.c q_stoq.c \ -+ mp_clz_tab.c q_dtoq.c q_flt.c q_neg.c q_qtos.c q_sub.c \ -+ q_add.c q_feq.c q_fne.c q_qtod.c q_qtou.c q_ulltoq.c \ -+ q_cmp.c q_fge.c q_itoq.c q_qtoull.c q_util.c \ -+ q_cmpe.c q_fgt.c q_lltoq.c q_qtoi.c q_sqrt.c q_utoq.c, soft-fp/$(f)) -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/double.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/double.h ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/double.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/double.h 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,264 @@ -+/* Software floating-point emulation. -+ Definitions for IEEE Double Precision -+ Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com), -+ Jakub Jelinek (jj@ultra.linux.cz), -+ David S. Miller (davem@redhat.com) and -+ Peter Maydell (pmaydell@chiark.greenend.org.uk). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ In addition to the permissions in the GNU Lesser General Public -+ License, the Free Software Foundation gives you unlimited -+ permission to link the compiled version of this file into -+ combinations with other programs, and to distribute those -+ combinations without any restriction coming from the use of this -+ file. (The Lesser General Public License restrictions do apply in -+ other respects; for example, they cover modification of the file, -+ and distribution when not linked into a combine executable.) -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -+ MA 02110-1301, USA. */ -+ -+#if _FP_W_TYPE_SIZE < 32 -+#error "Here's a nickel kid. Go buy yourself a real computer." -+#endif -+ -+#if _FP_W_TYPE_SIZE < 64 -+#define _FP_FRACTBITS_D (2 * _FP_W_TYPE_SIZE) -+#else -+#define _FP_FRACTBITS_D _FP_W_TYPE_SIZE -+#endif -+ -+#define _FP_FRACBITS_D 53 -+#define _FP_FRACXBITS_D (_FP_FRACTBITS_D - _FP_FRACBITS_D) -+#define _FP_WFRACBITS_D (_FP_WORKBITS + _FP_FRACBITS_D) -+#define _FP_WFRACXBITS_D (_FP_FRACTBITS_D - _FP_WFRACBITS_D) -+#define _FP_EXPBITS_D 11 -+#define _FP_EXPBIAS_D 1023 -+#define _FP_EXPMAX_D 2047 -+ -+#define _FP_QNANBIT_D \ -+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE) -+#define _FP_QNANBIT_SH_D \ -+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) -+#define _FP_IMPLBIT_D \ -+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE) -+#define _FP_IMPLBIT_SH_D \ -+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) -+#define _FP_OVERFLOW_D \ -+ ((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE) -+ -+typedef float DFtype __attribute__((mode(DF))); -+ -+#if _FP_W_TYPE_SIZE < 64 -+ -+union _FP_UNION_D -+{ -+ DFtype flt; -+ struct { -+#if __BYTE_ORDER == __BIG_ENDIAN -+ unsigned sign : 1; -+ unsigned exp : _FP_EXPBITS_D; -+ unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; -+ unsigned frac0 : _FP_W_TYPE_SIZE; -+#else -+ unsigned frac0 : _FP_W_TYPE_SIZE; -+ unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; -+ unsigned exp : _FP_EXPBITS_D; -+ unsigned sign : 1; -+#endif -+ } bits __attribute__((packed)); -+}; -+ -+#define FP_DECL_D(X) _FP_DECL(2,X) -+#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val) -+#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_2_P(D,X,val) -+#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_2(D,val,X) -+#define FP_PACK_RAW_DP(val,X) \ -+ do { \ -+ if (!FP_INHIBIT_RESULTS) \ -+ _FP_PACK_RAW_2_P(D,val,X); \ -+ } while (0) -+ -+#define FP_UNPACK_D(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_2(D,X,val); \ -+ _FP_UNPACK_CANONICAL(D,2,X); \ -+ } while (0) -+ -+#define FP_UNPACK_DP(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_2_P(D,X,val); \ -+ _FP_UNPACK_CANONICAL(D,2,X); \ -+ } while (0) -+ -+#define FP_UNPACK_SEMIRAW_D(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_2(D,X,val); \ -+ _FP_UNPACK_SEMIRAW(D,2,X); \ -+ } while (0) -+ -+#define FP_UNPACK_SEMIRAW_DP(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_2_P(D,X,val); \ -+ _FP_UNPACK_SEMIRAW(D,2,X); \ -+ } while (0) -+ -+#define FP_PACK_D(val,X) \ -+ do { \ -+ _FP_PACK_CANONICAL(D,2,X); \ -+ _FP_PACK_RAW_2(D,val,X); \ -+ } while (0) -+ -+#define FP_PACK_DP(val,X) \ -+ do { \ -+ _FP_PACK_CANONICAL(D,2,X); \ -+ if (!FP_INHIBIT_RESULTS) \ -+ _FP_PACK_RAW_2_P(D,val,X); \ -+ } while (0) -+ -+#define FP_PACK_SEMIRAW_D(val,X) \ -+ do { \ -+ _FP_PACK_SEMIRAW(D,2,X); \ -+ _FP_PACK_RAW_2(D,val,X); \ -+ } while (0) -+ -+#define FP_PACK_SEMIRAW_DP(val,X) \ -+ do { \ -+ _FP_PACK_SEMIRAW(D,2,X); \ -+ if (!FP_INHIBIT_RESULTS) \ -+ _FP_PACK_RAW_2_P(D,val,X); \ -+ } while (0) -+ -+#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,2,X) -+#define FP_NEG_D(R,X) _FP_NEG(D,2,R,X) -+#define FP_ADD_D(R,X,Y) _FP_ADD(D,2,R,X,Y) -+#define FP_SUB_D(R,X,Y) _FP_SUB(D,2,R,X,Y) -+#define FP_MUL_D(R,X,Y) _FP_MUL(D,2,R,X,Y) -+#define FP_DIV_D(R,X,Y) _FP_DIV(D,2,R,X,Y) -+#define FP_SQRT_D(R,X) _FP_SQRT(D,2,R,X) -+#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q) -+ -+#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,2,r,X,Y,un) -+#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,2,r,X,Y) -+#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,2,r,X,Y) -+ -+#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,2,r,X,rsz,rsg) -+#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,2,X,r,rs,rt) -+ -+#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_2(X) -+#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_2(X) -+ -+#else -+ -+union _FP_UNION_D -+{ -+ DFtype flt; -+ struct { -+#if __BYTE_ORDER == __BIG_ENDIAN -+ unsigned sign : 1; -+ unsigned exp : _FP_EXPBITS_D; -+ _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); -+#else -+ _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); -+ unsigned exp : _FP_EXPBITS_D; -+ unsigned sign : 1; -+#endif -+ } bits __attribute__((packed)); -+}; -+ -+#define FP_DECL_D(X) _FP_DECL(1,X) -+#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val) -+#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_1_P(D,X,val) -+#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_1(D,val,X) -+#define FP_PACK_RAW_DP(val,X) \ -+ do { \ -+ if (!FP_INHIBIT_RESULTS) \ -+ _FP_PACK_RAW_1_P(D,val,X); \ -+ } while (0) -+ -+#define FP_UNPACK_D(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_1(D,X,val); \ -+ _FP_UNPACK_CANONICAL(D,1,X); \ -+ } while (0) -+ -+#define FP_UNPACK_DP(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_1_P(D,X,val); \ -+ _FP_UNPACK_CANONICAL(D,1,X); \ -+ } while (0) -+ -+#define FP_UNPACK_SEMIRAW_D(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_2(1,X,val); \ -+ _FP_UNPACK_SEMIRAW(D,1,X); \ -+ } while (0) -+ -+#define FP_UNPACK_SEMIRAW_DP(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_2_P(1,X,val); \ -+ _FP_UNPACK_SEMIRAW(D,1,X); \ -+ } while (0) -+ -+#define FP_PACK_D(val,X) \ -+ do { \ -+ _FP_PACK_CANONICAL(D,1,X); \ -+ _FP_PACK_RAW_1(D,val,X); \ -+ } while (0) -+ -+#define FP_PACK_DP(val,X) \ -+ do { \ -+ _FP_PACK_CANONICAL(D,1,X); \ -+ if (!FP_INHIBIT_RESULTS) \ -+ _FP_PACK_RAW_1_P(D,val,X); \ -+ } while (0) -+ -+#define FP_PACK_SEMIRAW_D(val,X) \ -+ do { \ -+ _FP_PACK_SEMIRAW(D,1,X); \ -+ _FP_PACK_RAW_1(D,val,X); \ -+ } while (0) -+ -+#define FP_PACK_SEMIRAW_DP(val,X) \ -+ do { \ -+ _FP_PACK_SEMIRAW(D,1,X); \ -+ if (!FP_INHIBIT_RESULTS) \ -+ _FP_PACK_RAW_1_P(D,val,X); \ -+ } while (0) -+ -+#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,1,X) -+#define FP_NEG_D(R,X) _FP_NEG(D,1,R,X) -+#define FP_ADD_D(R,X,Y) _FP_ADD(D,1,R,X,Y) -+#define FP_SUB_D(R,X,Y) _FP_SUB(D,1,R,X,Y) -+#define FP_MUL_D(R,X,Y) _FP_MUL(D,1,R,X,Y) -+#define FP_DIV_D(R,X,Y) _FP_DIV(D,1,R,X,Y) -+#define FP_SQRT_D(R,X) _FP_SQRT(D,1,R,X) -+#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q) -+ -+/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by -+ the target machine. */ -+ -+#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,1,r,X,Y,un) -+#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y) -+#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,1,r,X,Y) -+ -+#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg) -+#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt) -+ -+#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_1(X) -+#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_1(X) -+ -+#endif /* W_TYPE_SIZE < 64 */ -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/extended.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/extended.h ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/extended.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/extended.h 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,431 @@ -+/* Software floating-point emulation. -+ Definitions for IEEE Extended Precision. -+ Copyright (C) 1999,2006,2007 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ In addition to the permissions in the GNU Lesser General Public -+ License, the Free Software Foundation gives you unlimited -+ permission to link the compiled version of this file into -+ combinations with other programs, and to distribute those -+ combinations without any restriction coming from the use of this -+ file. (The Lesser General Public License restrictions do apply in -+ other respects; for example, they cover modification of the file, -+ and distribution when not linked into a combine executable.) -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -+ MA 02110-1301, USA. */ -+ -+#if _FP_W_TYPE_SIZE < 32 -+#error "Here's a nickel, kid. Go buy yourself a real computer." -+#endif -+ -+#if _FP_W_TYPE_SIZE < 64 -+#define _FP_FRACTBITS_E (4*_FP_W_TYPE_SIZE) -+#else -+#define _FP_FRACTBITS_E (2*_FP_W_TYPE_SIZE) -+#endif -+ -+#define _FP_FRACBITS_E 64 -+#define _FP_FRACXBITS_E (_FP_FRACTBITS_E - _FP_FRACBITS_E) -+#define _FP_WFRACBITS_E (_FP_WORKBITS + _FP_FRACBITS_E) -+#define _FP_WFRACXBITS_E (_FP_FRACTBITS_E - _FP_WFRACBITS_E) -+#define _FP_EXPBITS_E 15 -+#define _FP_EXPBIAS_E 16383 -+#define _FP_EXPMAX_E 32767 -+ -+#define _FP_QNANBIT_E \ -+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE) -+#define _FP_QNANBIT_SH_E \ -+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) -+#define _FP_IMPLBIT_E \ -+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE) -+#define _FP_IMPLBIT_SH_E \ -+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) -+#define _FP_OVERFLOW_E \ -+ ((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE)) -+ -+typedef float XFtype __attribute__((mode(XF))); -+ -+#if _FP_W_TYPE_SIZE < 64 -+ -+union _FP_UNION_E -+{ -+ XFtype flt; -+ struct -+ { -+#if __BYTE_ORDER == __BIG_ENDIAN -+ unsigned long pad1 : _FP_W_TYPE_SIZE; -+ unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); -+ unsigned long sign : 1; -+ unsigned long exp : _FP_EXPBITS_E; -+ unsigned long frac1 : _FP_W_TYPE_SIZE; -+ unsigned long frac0 : _FP_W_TYPE_SIZE; -+#else -+ unsigned long frac0 : _FP_W_TYPE_SIZE; -+ unsigned long frac1 : _FP_W_TYPE_SIZE; -+ unsigned exp : _FP_EXPBITS_E; -+ unsigned sign : 1; -+#endif /* not bigendian */ -+ } bits __attribute__((packed)); -+}; -+ -+ -+#define FP_DECL_E(X) _FP_DECL(4,X) -+ -+#define FP_UNPACK_RAW_E(X, val) \ -+ do { \ -+ union _FP_UNION_E _flo; _flo.flt = (val); \ -+ \ -+ X##_f[2] = 0; X##_f[3] = 0; \ -+ X##_f[0] = _flo.bits.frac0; \ -+ X##_f[1] = _flo.bits.frac1; \ -+ X##_e = _flo.bits.exp; \ -+ X##_s = _flo.bits.sign; \ -+ } while (0) -+ -+#define FP_UNPACK_RAW_EP(X, val) \ -+ do { \ -+ union _FP_UNION_E *_flo = \ -+ (union _FP_UNION_E *)(val); \ -+ \ -+ X##_f[2] = 0; X##_f[3] = 0; \ -+ X##_f[0] = _flo->bits.frac0; \ -+ X##_f[1] = _flo->bits.frac1; \ -+ X##_e = _flo->bits.exp; \ -+ X##_s = _flo->bits.sign; \ -+ } while (0) -+ -+#define FP_PACK_RAW_E(val, X) \ -+ do { \ -+ union _FP_UNION_E _flo; \ -+ \ -+ if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ -+ else X##_f[1] &= ~(_FP_IMPLBIT_E); \ -+ _flo.bits.frac0 = X##_f[0]; \ -+ _flo.bits.frac1 = X##_f[1]; \ -+ _flo.bits.exp = X##_e; \ -+ _flo.bits.sign = X##_s; \ -+ \ -+ (val) = _flo.flt; \ -+ } while (0) -+ -+#define FP_PACK_RAW_EP(val, X) \ -+ do { \ -+ if (!FP_INHIBIT_RESULTS) \ -+ { \ -+ union _FP_UNION_E *_flo = \ -+ (union _FP_UNION_E *)(val); \ -+ \ -+ if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ -+ else X##_f[1] &= ~(_FP_IMPLBIT_E); \ -+ _flo->bits.frac0 = X##_f[0]; \ -+ _flo->bits.frac1 = X##_f[1]; \ -+ _flo->bits.exp = X##_e; \ -+ _flo->bits.sign = X##_s; \ -+ } \ -+ } while (0) -+ -+#define FP_UNPACK_E(X,val) \ -+ do { \ -+ FP_UNPACK_RAW_E(X,val); \ -+ _FP_UNPACK_CANONICAL(E,4,X); \ -+ } while (0) -+ -+#define FP_UNPACK_EP(X,val) \ -+ do { \ -+ FP_UNPACK_RAW_EP(X,val); \ -+ _FP_UNPACK_CANONICAL(E,4,X); \ -+ } while (0) -+ -+#define FP_UNPACK_SEMIRAW_E(X,val) \ -+ do { \ -+ FP_UNPACK_RAW_E(X,val); \ -+ _FP_UNPACK_SEMIRAW(E,4,X); \ -+ } while (0) -+ -+#define FP_UNPACK_SEMIRAW_EP(X,val) \ -+ do { \ -+ FP_UNPACK_RAW_EP(X,val); \ -+ _FP_UNPACK_SEMIRAW(E,4,X); \ -+ } while (0) -+ -+#define FP_PACK_E(val,X) \ -+ do { \ -+ _FP_PACK_CANONICAL(E,4,X); \ -+ FP_PACK_RAW_E(val,X); \ -+ } while (0) -+ -+#define FP_PACK_EP(val,X) \ -+ do { \ -+ _FP_PACK_CANONICAL(E,4,X); \ -+ FP_PACK_RAW_EP(val,X); \ -+ } while (0) -+ -+#define FP_PACK_SEMIRAW_E(val,X) \ -+ do { \ -+ _FP_PACK_SEMIRAW(E,4,X); \ -+ FP_PACK_RAW_E(val,X); \ -+ } while (0) -+ -+#define FP_PACK_SEMIRAW_EP(val,X) \ -+ do { \ -+ _FP_PACK_SEMIRAW(E,4,X); \ -+ FP_PACK_RAW_EP(val,X); \ -+ } while (0) -+ -+#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,4,X) -+#define FP_NEG_E(R,X) _FP_NEG(E,4,R,X) -+#define FP_ADD_E(R,X,Y) _FP_ADD(E,4,R,X,Y) -+#define FP_SUB_E(R,X,Y) _FP_SUB(E,4,R,X,Y) -+#define FP_MUL_E(R,X,Y) _FP_MUL(E,4,R,X,Y) -+#define FP_DIV_E(R,X,Y) _FP_DIV(E,4,R,X,Y) -+#define FP_SQRT_E(R,X) _FP_SQRT(E,4,R,X) -+ -+/* -+ * Square root algorithms: -+ * We have just one right now, maybe Newton approximation -+ * should be added for those machines where division is fast. -+ * This has special _E version because standard _4 square -+ * root would not work (it has to start normally with the -+ * second word and not the first), but as we have to do it -+ * anyway, we optimize it by doing most of the calculations -+ * in two UWtype registers instead of four. -+ */ -+ -+#define _FP_SQRT_MEAT_E(R, S, T, X, q) \ -+ do { \ -+ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ -+ _FP_FRAC_SRL_4(X, (_FP_WORKBITS)); \ -+ while (q) \ -+ { \ -+ T##_f[1] = S##_f[1] + q; \ -+ if (T##_f[1] <= X##_f[1]) \ -+ { \ -+ S##_f[1] = T##_f[1] + q; \ -+ X##_f[1] -= T##_f[1]; \ -+ R##_f[1] += q; \ -+ } \ -+ _FP_FRAC_SLL_2(X, 1); \ -+ q >>= 1; \ -+ } \ -+ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ -+ while (q) \ -+ { \ -+ T##_f[0] = S##_f[0] + q; \ -+ T##_f[1] = S##_f[1]; \ -+ if (T##_f[1] < X##_f[1] || \ -+ (T##_f[1] == X##_f[1] && \ -+ T##_f[0] <= X##_f[0])) \ -+ { \ -+ S##_f[0] = T##_f[0] + q; \ -+ S##_f[1] += (T##_f[0] > S##_f[0]); \ -+ _FP_FRAC_DEC_2(X, T); \ -+ R##_f[0] += q; \ -+ } \ -+ _FP_FRAC_SLL_2(X, 1); \ -+ q >>= 1; \ -+ } \ -+ _FP_FRAC_SLL_4(R, (_FP_WORKBITS)); \ -+ if (X##_f[0] | X##_f[1]) \ -+ { \ -+ if (S##_f[1] < X##_f[1] || \ -+ (S##_f[1] == X##_f[1] && \ -+ S##_f[0] < X##_f[0])) \ -+ R##_f[0] |= _FP_WORK_ROUND; \ -+ R##_f[0] |= _FP_WORK_STICKY; \ -+ } \ -+ } while (0) -+ -+#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,4,r,X,Y,un) -+#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,4,r,X,Y) -+#define FP_CMP_UNORD_E(r,X,Y) _FP_CMP_UNORD(E,4,r,X,Y) -+ -+#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,4,r,X,rsz,rsg) -+#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,4,X,r,rs,rt) -+ -+#define _FP_FRAC_HIGH_E(X) (X##_f[2]) -+#define _FP_FRAC_HIGH_RAW_E(X) (X##_f[1]) -+ -+#else /* not _FP_W_TYPE_SIZE < 64 */ -+union _FP_UNION_E -+{ -+ XFtype flt; -+ struct { -+#if __BYTE_ORDER == __BIG_ENDIAN -+ _FP_W_TYPE pad : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); -+ unsigned sign : 1; -+ unsigned exp : _FP_EXPBITS_E; -+ _FP_W_TYPE frac : _FP_W_TYPE_SIZE; -+#else -+ _FP_W_TYPE frac : _FP_W_TYPE_SIZE; -+ unsigned exp : _FP_EXPBITS_E; -+ unsigned sign : 1; -+#endif -+ } bits; -+}; -+ -+#define FP_DECL_E(X) _FP_DECL(2,X) -+ -+#define FP_UNPACK_RAW_E(X, val) \ -+ do { \ -+ union _FP_UNION_E _flo; _flo.flt = (val); \ -+ \ -+ X##_f0 = _flo.bits.frac; \ -+ X##_f1 = 0; \ -+ X##_e = _flo.bits.exp; \ -+ X##_s = _flo.bits.sign; \ -+ } while (0) -+ -+#define FP_UNPACK_RAW_EP(X, val) \ -+ do { \ -+ union _FP_UNION_E *_flo = \ -+ (union _FP_UNION_E *)(val); \ -+ \ -+ X##_f0 = _flo->bits.frac; \ -+ X##_f1 = 0; \ -+ X##_e = _flo->bits.exp; \ -+ X##_s = _flo->bits.sign; \ -+ } while (0) -+ -+#define FP_PACK_RAW_E(val, X) \ -+ do { \ -+ union _FP_UNION_E _flo; \ -+ \ -+ if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ -+ else X##_f0 &= ~(_FP_IMPLBIT_E); \ -+ _flo.bits.frac = X##_f0; \ -+ _flo.bits.exp = X##_e; \ -+ _flo.bits.sign = X##_s; \ -+ \ -+ (val) = _flo.flt; \ -+ } while (0) -+ -+#define FP_PACK_RAW_EP(fs, val, X) \ -+ do { \ -+ if (!FP_INHIBIT_RESULTS) \ -+ { \ -+ union _FP_UNION_E *_flo = \ -+ (union _FP_UNION_E *)(val); \ -+ \ -+ if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ -+ else X##_f0 &= ~(_FP_IMPLBIT_E); \ -+ _flo->bits.frac = X##_f0; \ -+ _flo->bits.exp = X##_e; \ -+ _flo->bits.sign = X##_s; \ -+ } \ -+ } while (0) -+ -+ -+#define FP_UNPACK_E(X,val) \ -+ do { \ -+ FP_UNPACK_RAW_E(X,val); \ -+ _FP_UNPACK_CANONICAL(E,2,X); \ -+ } while (0) -+ -+#define FP_UNPACK_EP(X,val) \ -+ do { \ -+ FP_UNPACK_RAW_EP(X,val); \ -+ _FP_UNPACK_CANONICAL(E,2,X); \ -+ } while (0) -+ -+#define FP_UNPACK_SEMIRAW_E(X,val) \ -+ do { \ -+ FP_UNPACK_RAW_E(X,val); \ -+ _FP_UNPACK_SEMIRAW(E,2,X); \ -+ } while (0) -+ -+#define FP_UNPACK_SEMIRAW_EP(X,val) \ -+ do { \ -+ FP_UNPACK_RAW_EP(X,val); \ -+ _FP_UNPACK_SEMIRAW(E,2,X); \ -+ } while (0) -+ -+#define FP_PACK_E(val,X) \ -+ do { \ -+ _FP_PACK_CANONICAL(E,2,X); \ -+ FP_PACK_RAW_E(val,X); \ -+ } while (0) -+ -+#define FP_PACK_EP(val,X) \ -+ do { \ -+ _FP_PACK_CANONICAL(E,2,X); \ -+ FP_PACK_RAW_EP(val,X); \ -+ } while (0) -+ -+#define FP_PACK_SEMIRAW_E(val,X) \ -+ do { \ -+ _FP_PACK_SEMIRAW(E,2,X); \ -+ FP_PACK_RAW_E(val,X); \ -+ } while (0) -+ -+#define FP_PACK_SEMIRAW_EP(val,X) \ -+ do { \ -+ _FP_PACK_SEMIRAW(E,2,X); \ -+ FP_PACK_RAW_EP(val,X); \ -+ } while (0) -+ -+#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,2,X) -+#define FP_NEG_E(R,X) _FP_NEG(E,2,R,X) -+#define FP_ADD_E(R,X,Y) _FP_ADD(E,2,R,X,Y) -+#define FP_SUB_E(R,X,Y) _FP_SUB(E,2,R,X,Y) -+#define FP_MUL_E(R,X,Y) _FP_MUL(E,2,R,X,Y) -+#define FP_DIV_E(R,X,Y) _FP_DIV(E,2,R,X,Y) -+#define FP_SQRT_E(R,X) _FP_SQRT(E,2,R,X) -+ -+/* -+ * Square root algorithms: -+ * We have just one right now, maybe Newton approximation -+ * should be added for those machines where division is fast. -+ * We optimize it by doing most of the calculations -+ * in one UWtype registers instead of two, although we don't -+ * have to. -+ */ -+#define _FP_SQRT_MEAT_E(R, S, T, X, q) \ -+ do { \ -+ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ -+ _FP_FRAC_SRL_2(X, (_FP_WORKBITS)); \ -+ while (q) \ -+ { \ -+ T##_f0 = S##_f0 + q; \ -+ if (T##_f0 <= X##_f0) \ -+ { \ -+ S##_f0 = T##_f0 + q; \ -+ X##_f0 -= T##_f0; \ -+ R##_f0 += q; \ -+ } \ -+ _FP_FRAC_SLL_1(X, 1); \ -+ q >>= 1; \ -+ } \ -+ _FP_FRAC_SLL_2(R, (_FP_WORKBITS)); \ -+ if (X##_f0) \ -+ { \ -+ if (S##_f0 < X##_f0) \ -+ R##_f0 |= _FP_WORK_ROUND; \ -+ R##_f0 |= _FP_WORK_STICKY; \ -+ } \ -+ } while (0) -+ -+#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,2,r,X,Y,un) -+#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,2,r,X,Y) -+#define FP_CMP_UNORD_E(r,X,Y) _FP_CMP_UNORD(E,2,r,X,Y) -+ -+#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,2,r,X,rsz,rsg) -+#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,2,X,r,rs,rt) -+ -+#define _FP_FRAC_HIGH_E(X) (X##_f1) -+#define _FP_FRAC_HIGH_RAW_E(X) (X##_f0) -+ -+#endif /* not _FP_W_TYPE_SIZE < 64 */ -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/longlong.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/longlong.h ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/longlong.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/longlong.h 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,1461 @@ -+/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. -+ Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -+ 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -+ -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+/* You have to define the following before including this file: -+ -+ UWtype -- An unsigned type, default type for operations (typically a "word") -+ UHWtype -- An unsigned type, at least half the size of UWtype. -+ UDWtype -- An unsigned type, at least twice as large a UWtype -+ W_TYPE_SIZE -- size in bits of UWtype -+ -+ UQItype -- Unsigned 8 bit type. -+ SItype, USItype -- Signed and unsigned 32 bit types. -+ DItype, UDItype -- Signed and unsigned 64 bit types. -+ -+ On a 32 bit machine UWtype should typically be USItype; -+ on a 64 bit machine, UWtype should typically be UDItype. */ -+ -+#define __BITS4 (W_TYPE_SIZE / 4) -+#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) -+#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) -+#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) -+ -+#ifndef W_TYPE_SIZE -+#define W_TYPE_SIZE 32 -+#define UWtype USItype -+#define UHWtype USItype -+#define UDWtype UDItype -+#endif -+ -+extern const UQItype __clz_tab[256] attribute_hidden; -+ -+/* Define auxiliary asm macros. -+ -+ 1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two -+ UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype -+ word product in HIGH_PROD and LOW_PROD. -+ -+ 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a -+ UDWtype product. This is just a variant of umul_ppmm. -+ -+ 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, -+ denominator) divides a UDWtype, composed by the UWtype integers -+ HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient -+ in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less -+ than DENOMINATOR for correct operation. If, in addition, the most -+ significant bit of DENOMINATOR must be 1, then the pre-processor symbol -+ UDIV_NEEDS_NORMALIZATION is defined to 1. -+ -+ 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, -+ denominator). Like udiv_qrnnd but the numbers are signed. The quotient -+ is rounded towards 0. -+ -+ 5) count_leading_zeros(count, x) counts the number of zero-bits from the -+ msb to the first nonzero bit in the UWtype X. This is the number of -+ steps X needs to be shifted left to set the msb. Undefined for X == 0, -+ unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. -+ -+ 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts -+ from the least significant end. -+ -+ 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, -+ high_addend_2, low_addend_2) adds two UWtype integers, composed by -+ HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 -+ respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow -+ (i.e. carry out) is not stored anywhere, and is lost. -+ -+ 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, -+ high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, -+ composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and -+ LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE -+ and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, -+ and is lost. -+ -+ If any of these macros are left undefined for a particular CPU, -+ C macros are used. */ -+ -+/* The CPUs come in alphabetical order below. -+ -+ Please add support for more CPUs here, or improve the current support -+ for the CPUs below! -+ (E.g. WE32100, IBM360.) */ -+ -+#if defined (__GNUC__) && !defined (NO_ASM) -+ -+/* We sometimes need to clobber "cc" with gcc2, but that would not be -+ understood by gcc1. Use cpp to avoid major code duplication. */ -+#if __GNUC__ < 2 -+#define __CLOBBER_CC -+#define __AND_CLOBBER_CC -+#else /* __GNUC__ >= 2 */ -+#define __CLOBBER_CC : "cc" -+#define __AND_CLOBBER_CC , "cc" -+#endif /* __GNUC__ < 2 */ -+ -+#if defined (__alpha) && W_TYPE_SIZE == 64 -+#define umul_ppmm(ph, pl, m0, m1) \ -+ do { \ -+ UDItype __m0 = (m0), __m1 = (m1); \ -+ (ph) = __builtin_alpha_umulh (__m0, __m1); \ -+ (pl) = __m0 * __m1; \ -+ } while (0) -+#define UMUL_TIME 46 -+#ifndef LONGLONG_STANDALONE -+#define udiv_qrnnd(q, r, n1, n0, d) \ -+ do { UDItype __r; \ -+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ -+ (r) = __r; \ -+ } while (0) -+extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); -+#define UDIV_TIME 220 -+#endif /* LONGLONG_STANDALONE */ -+#ifdef __alpha_cix__ -+#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clzl (X)) -+#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctzl (X)) -+#define COUNT_LEADING_ZEROS_0 64 -+#else -+#define count_leading_zeros(COUNT,X) \ -+ do { \ -+ UDItype __xr = (X), __t, __a; \ -+ __t = __builtin_alpha_cmpbge (0, __xr); \ -+ __a = __clz_tab[__t ^ 0xff] - 1; \ -+ __t = __builtin_alpha_extbl (__xr, __a); \ -+ (COUNT) = 64 - (__clz_tab[__t] + __a*8); \ -+ } while (0) -+#define count_trailing_zeros(COUNT,X) \ -+ do { \ -+ UDItype __xr = (X), __t, __a; \ -+ __t = __builtin_alpha_cmpbge (0, __xr); \ -+ __t = ~__t & -~__t; \ -+ __a = ((__t & 0xCC) != 0) * 2; \ -+ __a += ((__t & 0xF0) != 0) * 4; \ -+ __a += ((__t & 0xAA) != 0); \ -+ __t = __builtin_alpha_extbl (__xr, __a); \ -+ __a <<= 3; \ -+ __t &= -__t; \ -+ __a += ((__t & 0xCC) != 0) * 2; \ -+ __a += ((__t & 0xF0) != 0) * 4; \ -+ __a += ((__t & 0xAA) != 0); \ -+ (COUNT) = __a; \ -+ } while (0) -+#endif /* __alpha_cix__ */ -+#endif /* __alpha */ -+ -+#if defined (__arc__) && W_TYPE_SIZE == 32 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("add.f %1, %4, %5\n\tadc %0, %2, %3" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "%r" ((USItype) (ah)), \ -+ "rIJ" ((USItype) (bh)), \ -+ "%r" ((USItype) (al)), \ -+ "rIJ" ((USItype) (bl))) -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("sub.f %1, %4, %5\n\tsbc %0, %2, %3" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "r" ((USItype) (ah)), \ -+ "rIJ" ((USItype) (bh)), \ -+ "r" ((USItype) (al)), \ -+ "rIJ" ((USItype) (bl))) -+/* Call libgcc routine. */ -+#define umul_ppmm(w1, w0, u, v) \ -+do { \ -+ DWunion __w; \ -+ __w.ll = __umulsidi3 (u, v); \ -+ w1 = __w.s.high; \ -+ w0 = __w.s.low; \ -+} while (0) -+#define __umulsidi3 __umulsidi3 -+UDItype __umulsidi3 (USItype, USItype); -+#endif -+ -+#if defined (__arm__) && !defined (__thumb__) && W_TYPE_SIZE == 32 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("adds %1, %4, %5\n\tadc %0, %2, %3" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "%r" ((USItype) (ah)), \ -+ "rI" ((USItype) (bh)), \ -+ "%r" ((USItype) (al)), \ -+ "rI" ((USItype) (bl)) __CLOBBER_CC) -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("subs %1, %4, %5\n\tsbc %0, %2, %3" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "r" ((USItype) (ah)), \ -+ "rI" ((USItype) (bh)), \ -+ "r" ((USItype) (al)), \ -+ "rI" ((USItype) (bl)) __CLOBBER_CC) -+#define umul_ppmm(xh, xl, a, b) \ -+{register USItype __t0, __t1, __t2; \ -+ __asm__ ("%@ Inlined umul_ppmm\n" \ -+ " mov %2, %5, lsr #16\n" \ -+ " mov %0, %6, lsr #16\n" \ -+ " bic %3, %5, %2, lsl #16\n" \ -+ " bic %4, %6, %0, lsl #16\n" \ -+ " mul %1, %3, %4\n" \ -+ " mul %4, %2, %4\n" \ -+ " mul %3, %0, %3\n" \ -+ " mul %0, %2, %0\n" \ -+ " adds %3, %4, %3\n" \ -+ " addcs %0, %0, #65536\n" \ -+ " adds %1, %1, %3, lsl #16\n" \ -+ " adc %0, %0, %3, lsr #16" \ -+ : "=&r" ((USItype) (xh)), \ -+ "=r" ((USItype) (xl)), \ -+ "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ -+ : "r" ((USItype) (a)), \ -+ "r" ((USItype) (b)) __CLOBBER_CC );} -+#define UMUL_TIME 20 -+#define UDIV_TIME 100 -+#endif /* __arm__ */ -+ -+#if defined(__arm__) -+/* Let gcc decide how best to implement count_leading_zeros. */ -+#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) -+#define COUNT_LEADING_ZEROS_0 32 -+#endif -+ -+#if defined (__CRIS__) && __CRIS_arch_version >= 3 -+#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) -+#if __CRIS_arch_version >= 8 -+#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) -+#endif -+#endif /* __CRIS__ */ -+ -+#if defined (__hppa) && W_TYPE_SIZE == 32 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "%rM" ((USItype) (ah)), \ -+ "rM" ((USItype) (bh)), \ -+ "%rM" ((USItype) (al)), \ -+ "rM" ((USItype) (bl))) -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("sub %4,%5,%1\n\tsubb %2,%3,%0" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "rM" ((USItype) (ah)), \ -+ "rM" ((USItype) (bh)), \ -+ "rM" ((USItype) (al)), \ -+ "rM" ((USItype) (bl))) -+#if defined (_PA_RISC1_1) -+#define umul_ppmm(w1, w0, u, v) \ -+ do { \ -+ union \ -+ { \ -+ UDItype __f; \ -+ struct {USItype __w1, __w0;} __w1w0; \ -+ } __t; \ -+ __asm__ ("xmpyu %1,%2,%0" \ -+ : "=x" (__t.__f) \ -+ : "x" ((USItype) (u)), \ -+ "x" ((USItype) (v))); \ -+ (w1) = __t.__w1w0.__w1; \ -+ (w0) = __t.__w1w0.__w0; \ -+ } while (0) -+#define UMUL_TIME 8 -+#else -+#define UMUL_TIME 30 -+#endif -+#define UDIV_TIME 40 -+#define count_leading_zeros(count, x) \ -+ do { \ -+ USItype __tmp; \ -+ __asm__ ( \ -+ "ldi 1,%0\n" \ -+" extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \ -+" extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n"\ -+" ldo 16(%0),%0 ; Yes. Perform add.\n" \ -+" extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \ -+" extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n"\ -+" ldo 8(%0),%0 ; Yes. Perform add.\n" \ -+" extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \ -+" extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n"\ -+" ldo 4(%0),%0 ; Yes. Perform add.\n" \ -+" extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \ -+" extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n"\ -+" ldo 2(%0),%0 ; Yes. Perform add.\n" \ -+" extru %1,30,1,%1 ; Extract bit 1.\n" \ -+" sub %0,%1,%0 ; Subtract it.\n" \ -+ : "=r" (count), "=r" (__tmp) : "1" (x)); \ -+ } while (0) -+#endif -+ -+#if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32 -+#define smul_ppmm(xh, xl, m0, m1) \ -+ do { \ -+ union {DItype __ll; \ -+ struct {USItype __h, __l;} __i; \ -+ } __x; \ -+ __asm__ ("lr %N0,%1\n\tmr %0,%2" \ -+ : "=&r" (__x.__ll) \ -+ : "r" (m0), "r" (m1)); \ -+ (xh) = __x.__i.__h; (xl) = __x.__i.__l; \ -+ } while (0) -+#define sdiv_qrnnd(q, r, n1, n0, d) \ -+ do { \ -+ union {DItype __ll; \ -+ struct {USItype __h, __l;} __i; \ -+ } __x; \ -+ __x.__i.__h = n1; __x.__i.__l = n0; \ -+ __asm__ ("dr %0,%2" \ -+ : "=r" (__x.__ll) \ -+ : "0" (__x.__ll), "r" (d)); \ -+ (q) = __x.__i.__l; (r) = __x.__i.__h; \ -+ } while (0) -+#endif -+ -+#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("add{l} {%5,%1|%1,%5}\n\tadc{l} {%3,%0|%0,%3}" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "%0" ((USItype) (ah)), \ -+ "g" ((USItype) (bh)), \ -+ "%1" ((USItype) (al)), \ -+ "g" ((USItype) (bl))) -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("sub{l} {%5,%1|%1,%5}\n\tsbb{l} {%3,%0|%0,%3}" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "0" ((USItype) (ah)), \ -+ "g" ((USItype) (bh)), \ -+ "1" ((USItype) (al)), \ -+ "g" ((USItype) (bl))) -+#define umul_ppmm(w1, w0, u, v) \ -+ __asm__ ("mul{l} %3" \ -+ : "=a" ((USItype) (w0)), \ -+ "=d" ((USItype) (w1)) \ -+ : "%0" ((USItype) (u)), \ -+ "rm" ((USItype) (v))) -+#define udiv_qrnnd(q, r, n1, n0, dv) \ -+ __asm__ ("div{l} %4" \ -+ : "=a" ((USItype) (q)), \ -+ "=d" ((USItype) (r)) \ -+ : "0" ((USItype) (n0)), \ -+ "1" ((USItype) (n1)), \ -+ "rm" ((USItype) (dv))) -+#define count_leading_zeros(count, x) ((count) = __builtin_clz (x)) -+#define count_trailing_zeros(count, x) ((count) = __builtin_ctz (x)) -+#define UMUL_TIME 40 -+#define UDIV_TIME 40 -+#endif /* 80x86 */ -+ -+#if (defined (__x86_64__) || defined (__i386__)) && W_TYPE_SIZE == 64 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("add{q} {%5,%1|%1,%5}\n\tadc{q} {%3,%0|%0,%3}" \ -+ : "=r" ((UDItype) (sh)), \ -+ "=&r" ((UDItype) (sl)) \ -+ : "%0" ((UDItype) (ah)), \ -+ "rme" ((UDItype) (bh)), \ -+ "%1" ((UDItype) (al)), \ -+ "rme" ((UDItype) (bl))) -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("sub{q} {%5,%1|%1,%5}\n\tsbb{q} {%3,%0|%0,%3}" \ -+ : "=r" ((UDItype) (sh)), \ -+ "=&r" ((UDItype) (sl)) \ -+ : "0" ((UDItype) (ah)), \ -+ "rme" ((UDItype) (bh)), \ -+ "1" ((UDItype) (al)), \ -+ "rme" ((UDItype) (bl))) -+#define umul_ppmm(w1, w0, u, v) \ -+ __asm__ ("mul{q} %3" \ -+ : "=a" ((UDItype) (w0)), \ -+ "=d" ((UDItype) (w1)) \ -+ : "%0" ((UDItype) (u)), \ -+ "rm" ((UDItype) (v))) -+#define udiv_qrnnd(q, r, n1, n0, dv) \ -+ __asm__ ("div{q} %4" \ -+ : "=a" ((UDItype) (q)), \ -+ "=d" ((UDItype) (r)) \ -+ : "0" ((UDItype) (n0)), \ -+ "1" ((UDItype) (n1)), \ -+ "rm" ((UDItype) (dv))) -+#define count_leading_zeros(count, x) ((count) = __builtin_clzl (x)) -+#define count_trailing_zeros(count, x) ((count) = __builtin_ctzl (x)) -+#define UMUL_TIME 40 -+#define UDIV_TIME 40 -+#endif /* x86_64 */ -+ -+#if defined (__i960__) && W_TYPE_SIZE == 32 -+#define umul_ppmm(w1, w0, u, v) \ -+ ({union {UDItype __ll; \ -+ struct {USItype __l, __h;} __i; \ -+ } __xx; \ -+ __asm__ ("emul %2,%1,%0" \ -+ : "=d" (__xx.__ll) \ -+ : "%dI" ((USItype) (u)), \ -+ "dI" ((USItype) (v))); \ -+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) -+#define __umulsidi3(u, v) \ -+ ({UDItype __w; \ -+ __asm__ ("emul %2,%1,%0" \ -+ : "=d" (__w) \ -+ : "%dI" ((USItype) (u)), \ -+ "dI" ((USItype) (v))); \ -+ __w; }) -+#endif /* __i960__ */ -+ -+#if defined (__M32R__) && W_TYPE_SIZE == 32 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ /* The cmp clears the condition bit. */ \ -+ __asm__ ("cmp %0,%0\n\taddx %1,%5\n\taddx %0,%3" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "0" ((USItype) (ah)), \ -+ "r" ((USItype) (bh)), \ -+ "1" ((USItype) (al)), \ -+ "r" ((USItype) (bl)) \ -+ : "cbit") -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ /* The cmp clears the condition bit. */ \ -+ __asm__ ("cmp %0,%0\n\tsubx %1,%5\n\tsubx %0,%3" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "0" ((USItype) (ah)), \ -+ "r" ((USItype) (bh)), \ -+ "1" ((USItype) (al)), \ -+ "r" ((USItype) (bl)) \ -+ : "cbit") -+#endif /* __M32R__ */ -+ -+#if defined (__mc68000__) && W_TYPE_SIZE == 32 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \ -+ : "=d" ((USItype) (sh)), \ -+ "=&d" ((USItype) (sl)) \ -+ : "%0" ((USItype) (ah)), \ -+ "d" ((USItype) (bh)), \ -+ "%1" ((USItype) (al)), \ -+ "g" ((USItype) (bl))) -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \ -+ : "=d" ((USItype) (sh)), \ -+ "=&d" ((USItype) (sl)) \ -+ : "0" ((USItype) (ah)), \ -+ "d" ((USItype) (bh)), \ -+ "1" ((USItype) (al)), \ -+ "g" ((USItype) (bl))) -+ -+/* The '020, '030, '040, '060 and CPU32 have 32x32->64 and 64/32->32q-32r. */ -+#if (defined (__mc68020__) && !defined (__mc68060__)) -+#define umul_ppmm(w1, w0, u, v) \ -+ __asm__ ("mulu%.l %3,%1:%0" \ -+ : "=d" ((USItype) (w0)), \ -+ "=d" ((USItype) (w1)) \ -+ : "%0" ((USItype) (u)), \ -+ "dmi" ((USItype) (v))) -+#define UMUL_TIME 45 -+#define udiv_qrnnd(q, r, n1, n0, d) \ -+ __asm__ ("divu%.l %4,%1:%0" \ -+ : "=d" ((USItype) (q)), \ -+ "=d" ((USItype) (r)) \ -+ : "0" ((USItype) (n0)), \ -+ "1" ((USItype) (n1)), \ -+ "dmi" ((USItype) (d))) -+#define UDIV_TIME 90 -+#define sdiv_qrnnd(q, r, n1, n0, d) \ -+ __asm__ ("divs%.l %4,%1:%0" \ -+ : "=d" ((USItype) (q)), \ -+ "=d" ((USItype) (r)) \ -+ : "0" ((USItype) (n0)), \ -+ "1" ((USItype) (n1)), \ -+ "dmi" ((USItype) (d))) -+ -+#elif defined (__mcoldfire__) /* not mc68020 */ -+ -+#define umul_ppmm(xh, xl, a, b) \ -+ __asm__ ("| Inlined umul_ppmm\n" \ -+ " move%.l %2,%/d0\n" \ -+ " move%.l %3,%/d1\n" \ -+ " move%.l %/d0,%/d2\n" \ -+ " swap %/d0\n" \ -+ " move%.l %/d1,%/d3\n" \ -+ " swap %/d1\n" \ -+ " move%.w %/d2,%/d4\n" \ -+ " mulu %/d3,%/d4\n" \ -+ " mulu %/d1,%/d2\n" \ -+ " mulu %/d0,%/d3\n" \ -+ " mulu %/d0,%/d1\n" \ -+ " move%.l %/d4,%/d0\n" \ -+ " clr%.w %/d0\n" \ -+ " swap %/d0\n" \ -+ " add%.l %/d0,%/d2\n" \ -+ " add%.l %/d3,%/d2\n" \ -+ " jcc 1f\n" \ -+ " add%.l %#65536,%/d1\n" \ -+ "1: swap %/d2\n" \ -+ " moveq %#0,%/d0\n" \ -+ " move%.w %/d2,%/d0\n" \ -+ " move%.w %/d4,%/d2\n" \ -+ " move%.l %/d2,%1\n" \ -+ " add%.l %/d1,%/d0\n" \ -+ " move%.l %/d0,%0" \ -+ : "=g" ((USItype) (xh)), \ -+ "=g" ((USItype) (xl)) \ -+ : "g" ((USItype) (a)), \ -+ "g" ((USItype) (b)) \ -+ : "d0", "d1", "d2", "d3", "d4") -+#define UMUL_TIME 100 -+#define UDIV_TIME 400 -+#else /* not ColdFire */ -+/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX. */ -+#define umul_ppmm(xh, xl, a, b) \ -+ __asm__ ("| Inlined umul_ppmm\n" \ -+ " move%.l %2,%/d0\n" \ -+ " move%.l %3,%/d1\n" \ -+ " move%.l %/d0,%/d2\n" \ -+ " swap %/d0\n" \ -+ " move%.l %/d1,%/d3\n" \ -+ " swap %/d1\n" \ -+ " move%.w %/d2,%/d4\n" \ -+ " mulu %/d3,%/d4\n" \ -+ " mulu %/d1,%/d2\n" \ -+ " mulu %/d0,%/d3\n" \ -+ " mulu %/d0,%/d1\n" \ -+ " move%.l %/d4,%/d0\n" \ -+ " eor%.w %/d0,%/d0\n" \ -+ " swap %/d0\n" \ -+ " add%.l %/d0,%/d2\n" \ -+ " add%.l %/d3,%/d2\n" \ -+ " jcc 1f\n" \ -+ " add%.l %#65536,%/d1\n" \ -+ "1: swap %/d2\n" \ -+ " moveq %#0,%/d0\n" \ -+ " move%.w %/d2,%/d0\n" \ -+ " move%.w %/d4,%/d2\n" \ -+ " move%.l %/d2,%1\n" \ -+ " add%.l %/d1,%/d0\n" \ -+ " move%.l %/d0,%0" \ -+ : "=g" ((USItype) (xh)), \ -+ "=g" ((USItype) (xl)) \ -+ : "g" ((USItype) (a)), \ -+ "g" ((USItype) (b)) \ -+ : "d0", "d1", "d2", "d3", "d4") -+#define UMUL_TIME 100 -+#define UDIV_TIME 400 -+ -+#endif /* not mc68020 */ -+ -+/* The '020, '030, '040 and '060 have bitfield insns. -+ cpu32 disguises as a 68020, but lacks them. */ -+#if defined (__mc68020__) && !defined (__mcpu32__) -+#define count_leading_zeros(count, x) \ -+ __asm__ ("bfffo %1{%b2:%b2},%0" \ -+ : "=d" ((USItype) (count)) \ -+ : "od" ((USItype) (x)), "n" (0)) -+/* Some ColdFire architectures have a ff1 instruction supported via -+ __builtin_clz. */ -+#elif defined (__mcfisaaplus__) || defined (__mcfisac__) -+#define count_leading_zeros(count,x) ((count) = __builtin_clz (x)) -+#define COUNT_LEADING_ZEROS_0 32 -+#endif -+#endif /* mc68000 */ -+ -+#if defined (__m88000__) && W_TYPE_SIZE == 32 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "%rJ" ((USItype) (ah)), \ -+ "rJ" ((USItype) (bh)), \ -+ "%rJ" ((USItype) (al)), \ -+ "rJ" ((USItype) (bl))) -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "rJ" ((USItype) (ah)), \ -+ "rJ" ((USItype) (bh)), \ -+ "rJ" ((USItype) (al)), \ -+ "rJ" ((USItype) (bl))) -+#define count_leading_zeros(count, x) \ -+ do { \ -+ USItype __cbtmp; \ -+ __asm__ ("ff1 %0,%1" \ -+ : "=r" (__cbtmp) \ -+ : "r" ((USItype) (x))); \ -+ (count) = __cbtmp ^ 31; \ -+ } while (0) -+#define COUNT_LEADING_ZEROS_0 63 /* sic */ -+#if defined (__mc88110__) -+#define umul_ppmm(wh, wl, u, v) \ -+ do { \ -+ union {UDItype __ll; \ -+ struct {USItype __h, __l;} __i; \ -+ } __xx; \ -+ __asm__ ("mulu.d %0,%1,%2" \ -+ : "=r" (__xx.__ll) \ -+ : "r" ((USItype) (u)), \ -+ "r" ((USItype) (v))); \ -+ (wh) = __xx.__i.__h; \ -+ (wl) = __xx.__i.__l; \ -+ } while (0) -+#define udiv_qrnnd(q, r, n1, n0, d) \ -+ ({union {UDItype __ll; \ -+ struct {USItype __h, __l;} __i; \ -+ } __xx; \ -+ USItype __q; \ -+ __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ -+ __asm__ ("divu.d %0,%1,%2" \ -+ : "=r" (__q) \ -+ : "r" (__xx.__ll), \ -+ "r" ((USItype) (d))); \ -+ (r) = (n0) - __q * (d); (q) = __q; }) -+#define UMUL_TIME 5 -+#define UDIV_TIME 25 -+#else -+#define UMUL_TIME 17 -+#define UDIV_TIME 150 -+#endif /* __mc88110__ */ -+#endif /* __m88000__ */ -+ -+#if defined (__mips__) && W_TYPE_SIZE == 32 -+#define umul_ppmm(w1, w0, u, v) \ -+ do { \ -+ UDItype __x = (UDItype) (USItype) (u) * (USItype) (v); \ -+ (w1) = (USItype) (__x >> 32); \ -+ (w0) = (USItype) (__x); \ -+ } while (0) -+#define UMUL_TIME 10 -+#define UDIV_TIME 100 -+ -+#if (__mips == 32 || __mips == 64) && ! __mips16 -+#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) -+#define COUNT_LEADING_ZEROS_0 32 -+#endif -+#endif /* __mips__ */ -+ -+#if defined (__ns32000__) && W_TYPE_SIZE == 32 -+#define umul_ppmm(w1, w0, u, v) \ -+ ({union {UDItype __ll; \ -+ struct {USItype __l, __h;} __i; \ -+ } __xx; \ -+ __asm__ ("meid %2,%0" \ -+ : "=g" (__xx.__ll) \ -+ : "%0" ((USItype) (u)), \ -+ "g" ((USItype) (v))); \ -+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) -+#define __umulsidi3(u, v) \ -+ ({UDItype __w; \ -+ __asm__ ("meid %2,%0" \ -+ : "=g" (__w) \ -+ : "%0" ((USItype) (u)), \ -+ "g" ((USItype) (v))); \ -+ __w; }) -+#define udiv_qrnnd(q, r, n1, n0, d) \ -+ ({union {UDItype __ll; \ -+ struct {USItype __l, __h;} __i; \ -+ } __xx; \ -+ __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ -+ __asm__ ("deid %2,%0" \ -+ : "=g" (__xx.__ll) \ -+ : "0" (__xx.__ll), \ -+ "g" ((USItype) (d))); \ -+ (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) -+#define count_trailing_zeros(count,x) \ -+ do { \ -+ __asm__ ("ffsd %2,%0" \ -+ : "=r" ((USItype) (count)) \ -+ : "0" ((USItype) 0), \ -+ "r" ((USItype) (x))); \ -+ } while (0) -+#endif /* __ns32000__ */ -+ -+/* FIXME: We should test _IBMR2 here when we add assembly support for the -+ system vendor compilers. -+ FIXME: What's needed for gcc PowerPC VxWorks? __vxworks__ is not good -+ enough, since that hits ARM and m68k too. */ -+#if (defined (_ARCH_PPC) /* AIX */ \ -+ || defined (_ARCH_PWR) /* AIX */ \ -+ || defined (_ARCH_COM) /* AIX */ \ -+ || defined (__powerpc__) /* gcc */ \ -+ || defined (__POWERPC__) /* BEOS */ \ -+ || defined (__ppc__) /* Darwin */ \ -+ || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */ \ -+ || (defined (PPC) && defined (CPU_FAMILY) /* VxWorks */ \ -+ && CPU_FAMILY == PPC) \ -+ ) && W_TYPE_SIZE == 32 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ do { \ -+ if (__builtin_constant_p (bh) && (bh) == 0) \ -+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ -+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ -+ else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ -+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ -+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ -+ else \ -+ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ -+ : "=r" (sh), "=&r" (sl) \ -+ : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ -+ } while (0) -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ do { \ -+ if (__builtin_constant_p (ah) && (ah) == 0) \ -+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ -+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ -+ else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \ -+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ -+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ -+ else if (__builtin_constant_p (bh) && (bh) == 0) \ -+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ -+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ -+ else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ -+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ -+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ -+ else \ -+ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ -+ : "=r" (sh), "=&r" (sl) \ -+ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ -+ } while (0) -+#define count_leading_zeros(count, x) \ -+ __asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x)) -+#define COUNT_LEADING_ZEROS_0 32 -+#if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \ -+ || defined (__ppc__) \ -+ || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */ \ -+ || (defined (PPC) && defined (CPU_FAMILY) /* VxWorks */ \ -+ && CPU_FAMILY == PPC) -+#define umul_ppmm(ph, pl, m0, m1) \ -+ do { \ -+ USItype __m0 = (m0), __m1 = (m1); \ -+ __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ -+ (pl) = __m0 * __m1; \ -+ } while (0) -+#define UMUL_TIME 15 -+#define smul_ppmm(ph, pl, m0, m1) \ -+ do { \ -+ SItype __m0 = (m0), __m1 = (m1); \ -+ __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ -+ (pl) = __m0 * __m1; \ -+ } while (0) -+#define SMUL_TIME 14 -+#define UDIV_TIME 120 -+#elif defined (_ARCH_PWR) -+#define UMUL_TIME 8 -+#define smul_ppmm(xh, xl, m0, m1) \ -+ __asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1)) -+#define SMUL_TIME 4 -+#define sdiv_qrnnd(q, r, nh, nl, d) \ -+ __asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d)) -+#define UDIV_TIME 100 -+#endif -+#endif /* 32-bit POWER architecture variants. */ -+ -+/* We should test _IBMR2 here when we add assembly support for the system -+ vendor compilers. */ -+#if (defined (_ARCH_PPC64) || defined (__powerpc64__)) && W_TYPE_SIZE == 64 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ do { \ -+ if (__builtin_constant_p (bh) && (bh) == 0) \ -+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ -+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ -+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ -+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ -+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ -+ else \ -+ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ -+ : "=r" (sh), "=&r" (sl) \ -+ : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ -+ } while (0) -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ do { \ -+ if (__builtin_constant_p (ah) && (ah) == 0) \ -+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ -+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ -+ else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \ -+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ -+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ -+ else if (__builtin_constant_p (bh) && (bh) == 0) \ -+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ -+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ -+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ -+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ -+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ -+ else \ -+ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ -+ : "=r" (sh), "=&r" (sl) \ -+ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ -+ } while (0) -+#define count_leading_zeros(count, x) \ -+ __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x)) -+#define COUNT_LEADING_ZEROS_0 64 -+#define umul_ppmm(ph, pl, m0, m1) \ -+ do { \ -+ UDItype __m0 = (m0), __m1 = (m1); \ -+ __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ -+ (pl) = __m0 * __m1; \ -+ } while (0) -+#define UMUL_TIME 15 -+#define smul_ppmm(ph, pl, m0, m1) \ -+ do { \ -+ DItype __m0 = (m0), __m1 = (m1); \ -+ __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ -+ (pl) = __m0 * __m1; \ -+ } while (0) -+#define SMUL_TIME 14 /* ??? */ -+#define UDIV_TIME 120 /* ??? */ -+#endif /* 64-bit PowerPC. */ -+ -+#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("a %1,%5\n\tae %0,%3" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "%0" ((USItype) (ah)), \ -+ "r" ((USItype) (bh)), \ -+ "%1" ((USItype) (al)), \ -+ "r" ((USItype) (bl))) -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("s %1,%5\n\tse %0,%3" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "0" ((USItype) (ah)), \ -+ "r" ((USItype) (bh)), \ -+ "1" ((USItype) (al)), \ -+ "r" ((USItype) (bl))) -+#define umul_ppmm(ph, pl, m0, m1) \ -+ do { \ -+ USItype __m0 = (m0), __m1 = (m1); \ -+ __asm__ ( \ -+ "s r2,r2\n" \ -+" mts r10,%2\n" \ -+" m r2,%3\n" \ -+" m r2,%3\n" \ -+" m r2,%3\n" \ -+" m r2,%3\n" \ -+" m r2,%3\n" \ -+" m r2,%3\n" \ -+" m r2,%3\n" \ -+" m r2,%3\n" \ -+" m r2,%3\n" \ -+" m r2,%3\n" \ -+" m r2,%3\n" \ -+" m r2,%3\n" \ -+" m r2,%3\n" \ -+" m r2,%3\n" \ -+" m r2,%3\n" \ -+" m r2,%3\n" \ -+" cas %0,r2,r0\n" \ -+" mfs r10,%1" \ -+ : "=r" ((USItype) (ph)), \ -+ "=r" ((USItype) (pl)) \ -+ : "%r" (__m0), \ -+ "r" (__m1) \ -+ : "r2"); \ -+ (ph) += ((((SItype) __m0 >> 31) & __m1) \ -+ + (((SItype) __m1 >> 31) & __m0)); \ -+ } while (0) -+#define UMUL_TIME 20 -+#define UDIV_TIME 200 -+#define count_leading_zeros(count, x) \ -+ do { \ -+ if ((x) >= 0x10000) \ -+ __asm__ ("clz %0,%1" \ -+ : "=r" ((USItype) (count)) \ -+ : "r" ((USItype) (x) >> 16)); \ -+ else \ -+ { \ -+ __asm__ ("clz %0,%1" \ -+ : "=r" ((USItype) (count)) \ -+ : "r" ((USItype) (x))); \ -+ (count) += 16; \ -+ } \ -+ } while (0) -+#endif -+ -+#if defined(__sh__) && !__SHMEDIA__ && W_TYPE_SIZE == 32 -+#ifndef __sh1__ -+#define umul_ppmm(w1, w0, u, v) \ -+ __asm__ ( \ -+ "dmulu.l %2,%3\n\tsts%M1 macl,%1\n\tsts%M0 mach,%0" \ -+ : "=r<" ((USItype)(w1)), \ -+ "=r<" ((USItype)(w0)) \ -+ : "r" ((USItype)(u)), \ -+ "r" ((USItype)(v)) \ -+ : "macl", "mach") -+#define UMUL_TIME 5 -+#endif -+ -+/* This is the same algorithm as __udiv_qrnnd_c. */ -+#define UDIV_NEEDS_NORMALIZATION 1 -+ -+#define udiv_qrnnd(q, r, n1, n0, d) \ -+ do { \ -+ extern UWtype __udiv_qrnnd_16 (UWtype, UWtype) \ -+ __attribute__ ((visibility ("hidden"))); \ -+ /* r0: rn r1: qn */ /* r0: n1 r4: n0 r5: d r6: d1 */ /* r2: __m */ \ -+ __asm__ ( \ -+ "mov%M4 %4,r5\n" \ -+" swap.w %3,r4\n" \ -+" swap.w r5,r6\n" \ -+" jsr @%5\n" \ -+" shll16 r6\n" \ -+" swap.w r4,r4\n" \ -+" jsr @%5\n" \ -+" swap.w r1,%0\n" \ -+" or r1,%0" \ -+ : "=r" (q), "=&z" (r) \ -+ : "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16) \ -+ : "r1", "r2", "r4", "r5", "r6", "pr"); \ -+ } while (0) -+ -+#define UDIV_TIME 80 -+ -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("clrt;subc %5,%1; subc %4,%0" \ -+ : "=r" (sh), "=r" (sl) \ -+ : "0" (ah), "1" (al), "r" (bh), "r" (bl)) -+ -+#endif /* __sh__ */ -+ -+#if defined (__SH5__) && __SHMEDIA__ && W_TYPE_SIZE == 32 -+#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v) -+#define count_leading_zeros(count, x) \ -+ do \ -+ { \ -+ UDItype x_ = (USItype)(x); \ -+ SItype c_; \ -+ \ -+ __asm__ ("nsb %1, %0" : "=r" (c_) : "r" (x_)); \ -+ (count) = c_ - 31; \ -+ } \ -+ while (0) -+#define COUNT_LEADING_ZEROS_0 32 -+#endif -+ -+#if defined (__sparc__) && !defined (__arch64__) && !defined (__sparcv9) \ -+ && W_TYPE_SIZE == 32 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "%rJ" ((USItype) (ah)), \ -+ "rI" ((USItype) (bh)), \ -+ "%rJ" ((USItype) (al)), \ -+ "rI" ((USItype) (bl)) \ -+ __CLOBBER_CC) -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0" \ -+ : "=r" ((USItype) (sh)), \ -+ "=&r" ((USItype) (sl)) \ -+ : "rJ" ((USItype) (ah)), \ -+ "rI" ((USItype) (bh)), \ -+ "rJ" ((USItype) (al)), \ -+ "rI" ((USItype) (bl)) \ -+ __CLOBBER_CC) -+#if defined (__sparc_v8__) -+#define umul_ppmm(w1, w0, u, v) \ -+ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ -+ : "=r" ((USItype) (w1)), \ -+ "=r" ((USItype) (w0)) \ -+ : "r" ((USItype) (u)), \ -+ "r" ((USItype) (v))) -+#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ -+ __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\ -+ : "=&r" ((USItype) (__q)), \ -+ "=&r" ((USItype) (__r)) \ -+ : "r" ((USItype) (__n1)), \ -+ "r" ((USItype) (__n0)), \ -+ "r" ((USItype) (__d))) -+#else -+#if defined (__sparclite__) -+/* This has hardware multiply but not divide. It also has two additional -+ instructions scan (ffs from high bit) and divscc. */ -+#define umul_ppmm(w1, w0, u, v) \ -+ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ -+ : "=r" ((USItype) (w1)), \ -+ "=r" ((USItype) (w0)) \ -+ : "r" ((USItype) (u)), \ -+ "r" ((USItype) (v))) -+#define udiv_qrnnd(q, r, n1, n0, d) \ -+ __asm__ ("! Inlined udiv_qrnnd\n" \ -+" wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \ -+" tst %%g0\n" \ -+" divscc %3,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%%g1\n" \ -+" divscc %%g1,%4,%0\n" \ -+" rd %%y,%1\n" \ -+" bl,a 1f\n" \ -+" add %1,%4,%1\n" \ -+"1: ! End of inline udiv_qrnnd" \ -+ : "=r" ((USItype) (q)), \ -+ "=r" ((USItype) (r)) \ -+ : "r" ((USItype) (n1)), \ -+ "r" ((USItype) (n0)), \ -+ "rI" ((USItype) (d)) \ -+ : "g1" __AND_CLOBBER_CC) -+#define UDIV_TIME 37 -+#define count_leading_zeros(count, x) \ -+ do { \ -+ __asm__ ("scan %1,1,%0" \ -+ : "=r" ((USItype) (count)) \ -+ : "r" ((USItype) (x))); \ -+ } while (0) -+/* Early sparclites return 63 for an argument of 0, but they warn that future -+ implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 -+ undefined. */ -+#else -+/* SPARC without integer multiplication and divide instructions. -+ (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */ -+#define umul_ppmm(w1, w0, u, v) \ -+ __asm__ ("! Inlined umul_ppmm\n" \ -+" wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n"\ -+" sra %3,31,%%o5 ! Don't move this insn\n" \ -+" and %2,%%o5,%%o5 ! Don't move this insn\n" \ -+" andcc %%g0,0,%%g1 ! Don't move this insn\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,%3,%%g1\n" \ -+" mulscc %%g1,0,%%g1\n" \ -+" add %%g1,%%o5,%0\n" \ -+" rd %%y,%1" \ -+ : "=r" ((USItype) (w1)), \ -+ "=r" ((USItype) (w0)) \ -+ : "%rI" ((USItype) (u)), \ -+ "r" ((USItype) (v)) \ -+ : "g1", "o5" __AND_CLOBBER_CC) -+#define UMUL_TIME 39 /* 39 instructions */ -+/* It's quite necessary to add this much assembler for the sparc. -+ The default udiv_qrnnd (in C) is more than 10 times slower! */ -+#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ -+ __asm__ ("! Inlined udiv_qrnnd\n" \ -+" mov 32,%%g1\n" \ -+" subcc %1,%2,%%g0\n" \ -+"1: bcs 5f\n" \ -+" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ -+" sub %1,%2,%1 ! this kills msb of n\n" \ -+" addx %1,%1,%1 ! so this can't give carry\n" \ -+" subcc %%g1,1,%%g1\n" \ -+"2: bne 1b\n" \ -+" subcc %1,%2,%%g0\n" \ -+" bcs 3f\n" \ -+" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ -+" b 3f\n" \ -+" sub %1,%2,%1 ! this kills msb of n\n" \ -+"4: sub %1,%2,%1\n" \ -+"5: addxcc %1,%1,%1\n" \ -+" bcc 2b\n" \ -+" subcc %%g1,1,%%g1\n" \ -+"! Got carry from n. Subtract next step to cancel this carry.\n" \ -+" bne 4b\n" \ -+" addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n" \ -+" sub %1,%2,%1\n" \ -+"3: xnor %0,0,%0\n" \ -+" ! End of inline udiv_qrnnd" \ -+ : "=&r" ((USItype) (__q)), \ -+ "=&r" ((USItype) (__r)) \ -+ : "r" ((USItype) (__d)), \ -+ "1" ((USItype) (__n1)), \ -+ "0" ((USItype) (__n0)) : "g1" __AND_CLOBBER_CC) -+#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ -+#endif /* __sparclite__ */ -+#endif /* __sparc_v8__ */ -+#endif /* sparc32 */ -+ -+#if ((defined (__sparc__) && defined (__arch64__)) || defined (__sparcv9)) \ -+ && W_TYPE_SIZE == 64 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("addcc %r4,%5,%1\n\t" \ -+ "add %r2,%3,%0\n\t" \ -+ "bcs,a,pn %%xcc, 1f\n\t" \ -+ "add %0, 1, %0\n" \ -+ "1:" \ -+ : "=r" ((UDItype)(sh)), \ -+ "=&r" ((UDItype)(sl)) \ -+ : "%rJ" ((UDItype)(ah)), \ -+ "rI" ((UDItype)(bh)), \ -+ "%rJ" ((UDItype)(al)), \ -+ "rI" ((UDItype)(bl)) \ -+ __CLOBBER_CC) -+ -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("subcc %r4,%5,%1\n\t" \ -+ "sub %r2,%3,%0\n\t" \ -+ "bcs,a,pn %%xcc, 1f\n\t" \ -+ "sub %0, 1, %0\n\t" \ -+ "1:" \ -+ : "=r" ((UDItype)(sh)), \ -+ "=&r" ((UDItype)(sl)) \ -+ : "rJ" ((UDItype)(ah)), \ -+ "rI" ((UDItype)(bh)), \ -+ "rJ" ((UDItype)(al)), \ -+ "rI" ((UDItype)(bl)) \ -+ __CLOBBER_CC) -+ -+#define umul_ppmm(wh, wl, u, v) \ -+ do { \ -+ UDItype tmp1, tmp2, tmp3, tmp4; \ -+ __asm__ __volatile__ ( \ -+ "srl %7,0,%3\n\t" \ -+ "mulx %3,%6,%1\n\t" \ -+ "srlx %6,32,%2\n\t" \ -+ "mulx %2,%3,%4\n\t" \ -+ "sllx %4,32,%5\n\t" \ -+ "srl %6,0,%3\n\t" \ -+ "sub %1,%5,%5\n\t" \ -+ "srlx %5,32,%5\n\t" \ -+ "addcc %4,%5,%4\n\t" \ -+ "srlx %7,32,%5\n\t" \ -+ "mulx %3,%5,%3\n\t" \ -+ "mulx %2,%5,%5\n\t" \ -+ "sethi %%hi(0x80000000),%2\n\t" \ -+ "addcc %4,%3,%4\n\t" \ -+ "srlx %4,32,%4\n\t" \ -+ "add %2,%2,%2\n\t" \ -+ "movcc %%xcc,%%g0,%2\n\t" \ -+ "addcc %5,%4,%5\n\t" \ -+ "sllx %3,32,%3\n\t" \ -+ "add %1,%3,%1\n\t" \ -+ "add %5,%2,%0" \ -+ : "=r" ((UDItype)(wh)), \ -+ "=&r" ((UDItype)(wl)), \ -+ "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \ -+ : "r" ((UDItype)(u)), \ -+ "r" ((UDItype)(v)) \ -+ __CLOBBER_CC); \ -+ } while (0) -+#define UMUL_TIME 96 -+#define UDIV_TIME 230 -+#endif /* sparc64 */ -+ -+#if defined (__vax__) && W_TYPE_SIZE == 32 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("addl2 %5,%1\n\tadwc %3,%0" \ -+ : "=g" ((USItype) (sh)), \ -+ "=&g" ((USItype) (sl)) \ -+ : "%0" ((USItype) (ah)), \ -+ "g" ((USItype) (bh)), \ -+ "%1" ((USItype) (al)), \ -+ "g" ((USItype) (bl))) -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("subl2 %5,%1\n\tsbwc %3,%0" \ -+ : "=g" ((USItype) (sh)), \ -+ "=&g" ((USItype) (sl)) \ -+ : "0" ((USItype) (ah)), \ -+ "g" ((USItype) (bh)), \ -+ "1" ((USItype) (al)), \ -+ "g" ((USItype) (bl))) -+#define umul_ppmm(xh, xl, m0, m1) \ -+ do { \ -+ union { \ -+ UDItype __ll; \ -+ struct {USItype __l, __h;} __i; \ -+ } __xx; \ -+ USItype __m0 = (m0), __m1 = (m1); \ -+ __asm__ ("emul %1,%2,$0,%0" \ -+ : "=r" (__xx.__ll) \ -+ : "g" (__m0), \ -+ "g" (__m1)); \ -+ (xh) = __xx.__i.__h; \ -+ (xl) = __xx.__i.__l; \ -+ (xh) += ((((SItype) __m0 >> 31) & __m1) \ -+ + (((SItype) __m1 >> 31) & __m0)); \ -+ } while (0) -+#define sdiv_qrnnd(q, r, n1, n0, d) \ -+ do { \ -+ union {DItype __ll; \ -+ struct {SItype __l, __h;} __i; \ -+ } __xx; \ -+ __xx.__i.__h = n1; __xx.__i.__l = n0; \ -+ __asm__ ("ediv %3,%2,%0,%1" \ -+ : "=g" (q), "=g" (r) \ -+ : "g" (__xx.__ll), "g" (d)); \ -+ } while (0) -+#endif /* __vax__ */ -+ -+#if defined (__xtensa__) && W_TYPE_SIZE == 32 -+/* This code is not Xtensa-configuration-specific, so rely on the compiler -+ to expand builtin functions depending on what configuration features -+ are available. This avoids library calls when the operation can be -+ performed in-line. */ -+#define umul_ppmm(w1, w0, u, v) \ -+ do { \ -+ DWunion __w; \ -+ __w.ll = __builtin_umulsidi3 (u, v); \ -+ w1 = __w.s.high; \ -+ w0 = __w.s.low; \ -+ } while (0) -+#define __umulsidi3(u, v) __builtin_umulsidi3 (u, v) -+#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) -+#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) -+#endif /* __xtensa__ */ -+ -+#if defined (__z8000__) && W_TYPE_SIZE == 16 -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ -+ : "=r" ((unsigned int)(sh)), \ -+ "=&r" ((unsigned int)(sl)) \ -+ : "%0" ((unsigned int)(ah)), \ -+ "r" ((unsigned int)(bh)), \ -+ "%1" ((unsigned int)(al)), \ -+ "rQR" ((unsigned int)(bl))) -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ -+ : "=r" ((unsigned int)(sh)), \ -+ "=&r" ((unsigned int)(sl)) \ -+ : "0" ((unsigned int)(ah)), \ -+ "r" ((unsigned int)(bh)), \ -+ "1" ((unsigned int)(al)), \ -+ "rQR" ((unsigned int)(bl))) -+#define umul_ppmm(xh, xl, m0, m1) \ -+ do { \ -+ union {long int __ll; \ -+ struct {unsigned int __h, __l;} __i; \ -+ } __xx; \ -+ unsigned int __m0 = (m0), __m1 = (m1); \ -+ __asm__ ("mult %S0,%H3" \ -+ : "=r" (__xx.__i.__h), \ -+ "=r" (__xx.__i.__l) \ -+ : "%1" (__m0), \ -+ "rQR" (__m1)); \ -+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ -+ (xh) += ((((signed int) __m0 >> 15) & __m1) \ -+ + (((signed int) __m1 >> 15) & __m0)); \ -+ } while (0) -+#endif /* __z8000__ */ -+ -+#endif /* __GNUC__ */ -+ -+/* If this machine has no inline assembler, use C macros. */ -+ -+#if !defined (add_ssaaaa) -+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -+ do { \ -+ UWtype __x; \ -+ __x = (al) + (bl); \ -+ (sh) = (ah) + (bh) + (__x < (al)); \ -+ (sl) = __x; \ -+ } while (0) -+#endif -+ -+#if !defined (sub_ddmmss) -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ do { \ -+ UWtype __x; \ -+ __x = (al) - (bl); \ -+ (sh) = (ah) - (bh) - (__x > (al)); \ -+ (sl) = __x; \ -+ } while (0) -+#endif -+ -+/* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of -+ smul_ppmm. */ -+#if !defined (umul_ppmm) && defined (smul_ppmm) -+#define umul_ppmm(w1, w0, u, v) \ -+ do { \ -+ UWtype __w1; \ -+ UWtype __xm0 = (u), __xm1 = (v); \ -+ smul_ppmm (__w1, w0, __xm0, __xm1); \ -+ (w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1) \ -+ + (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0); \ -+ } while (0) -+#endif -+ -+/* If we still don't have umul_ppmm, define it using plain C. */ -+#if !defined (umul_ppmm) -+#define umul_ppmm(w1, w0, u, v) \ -+ do { \ -+ UWtype __x0, __x1, __x2, __x3; \ -+ UHWtype __ul, __vl, __uh, __vh; \ -+ \ -+ __ul = __ll_lowpart (u); \ -+ __uh = __ll_highpart (u); \ -+ __vl = __ll_lowpart (v); \ -+ __vh = __ll_highpart (v); \ -+ \ -+ __x0 = (UWtype) __ul * __vl; \ -+ __x1 = (UWtype) __ul * __vh; \ -+ __x2 = (UWtype) __uh * __vl; \ -+ __x3 = (UWtype) __uh * __vh; \ -+ \ -+ __x1 += __ll_highpart (__x0);/* this can't give carry */ \ -+ __x1 += __x2; /* but this indeed can */ \ -+ if (__x1 < __x2) /* did we get it? */ \ -+ __x3 += __ll_B; /* yes, add it in the proper pos. */ \ -+ \ -+ (w1) = __x3 + __ll_highpart (__x1); \ -+ (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ -+ } while (0) -+#endif -+ -+#if !defined (__umulsidi3) -+#define __umulsidi3(u, v) \ -+ ({DWunion __w; \ -+ umul_ppmm (__w.s.high, __w.s.low, u, v); \ -+ __w.ll; }) -+#endif -+ -+/* Define this unconditionally, so it can be used for debugging. */ -+#define __udiv_qrnnd_c(q, r, n1, n0, d) \ -+ do { \ -+ UWtype __d1, __d0, __q1, __q0; \ -+ UWtype __r1, __r0, __m; \ -+ __d1 = __ll_highpart (d); \ -+ __d0 = __ll_lowpart (d); \ -+ \ -+ __r1 = (n1) % __d1; \ -+ __q1 = (n1) / __d1; \ -+ __m = (UWtype) __q1 * __d0; \ -+ __r1 = __r1 * __ll_B | __ll_highpart (n0); \ -+ if (__r1 < __m) \ -+ { \ -+ __q1--, __r1 += (d); \ -+ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ -+ if (__r1 < __m) \ -+ __q1--, __r1 += (d); \ -+ } \ -+ __r1 -= __m; \ -+ \ -+ __r0 = __r1 % __d1; \ -+ __q0 = __r1 / __d1; \ -+ __m = (UWtype) __q0 * __d0; \ -+ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ -+ if (__r0 < __m) \ -+ { \ -+ __q0--, __r0 += (d); \ -+ if (__r0 >= (d)) \ -+ if (__r0 < __m) \ -+ __q0--, __r0 += (d); \ -+ } \ -+ __r0 -= __m; \ -+ \ -+ (q) = (UWtype) __q1 * __ll_B | __q0; \ -+ (r) = __r0; \ -+ } while (0) -+ -+/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through -+ __udiv_w_sdiv (defined in libgcc or elsewhere). */ -+#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) -+#define udiv_qrnnd(q, r, nh, nl, d) \ -+ do { \ -+ USItype __r; \ -+ (q) = __udiv_w_sdiv (&__r, nh, nl, d); \ -+ (r) = __r; \ -+ } while (0) -+#endif -+ -+/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ -+#if !defined (udiv_qrnnd) -+#define UDIV_NEEDS_NORMALIZATION 1 -+#define udiv_qrnnd __udiv_qrnnd_c -+#endif -+ -+#if !defined (count_leading_zeros) -+#define count_leading_zeros(count, x) \ -+ do { \ -+ UWtype __xr = (x); \ -+ UWtype __a; \ -+ \ -+ if (W_TYPE_SIZE <= 32) \ -+ { \ -+ __a = __xr < ((UWtype)1<<2*__BITS4) \ -+ ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \ -+ : (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ -+ } \ -+ else \ -+ { \ -+ for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ -+ if (((__xr >> __a) & 0xff) != 0) \ -+ break; \ -+ } \ -+ \ -+ (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ -+ } while (0) -+#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE -+#endif -+ -+#if !defined (count_trailing_zeros) -+/* Define count_trailing_zeros using count_leading_zeros. The latter might be -+ defined in asm, but if it is not, the C version above is good enough. */ -+#define count_trailing_zeros(count, x) \ -+ do { \ -+ UWtype __ctz_x = (x); \ -+ UWtype __ctz_c; \ -+ count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ -+ (count) = W_TYPE_SIZE - 1 - __ctz_c; \ -+ } while (0) -+#endif -+ -+#ifndef UDIV_NEEDS_NORMALIZATION -+#define UDIV_NEEDS_NORMALIZATION 0 -+#endif -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/mp_clz_tab.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/mp_clz_tab.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/mp_clz_tab.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/mp_clz_tab.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,37 @@ -+/* __clz_tab -- support for longlong.h -+ Copyright (C) 1991, 1993, 1994, 1997 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. Its master source is NOT part of -+ the C library, however. The master source lives in the GNU MP Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#if 0 -+#include -+#include "gmp-impl.h" -+#endif -+ -+const -+unsigned char __clz_tab[] = -+{ -+ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, -+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, -+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, -+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, -+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, -+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, -+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, -+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, -+}; -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-1.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-1.h ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-1.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-1.h 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,302 @@ -+/* Software floating-point emulation. -+ Basic one-word fraction declaration and manipulation. -+ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com), -+ Jakub Jelinek (jj@ultra.linux.cz), -+ David S. Miller (davem@redhat.com) and -+ Peter Maydell (pmaydell@chiark.greenend.org.uk). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ In addition to the permissions in the GNU Lesser General Public -+ License, the Free Software Foundation gives you unlimited -+ permission to link the compiled version of this file into -+ combinations with other programs, and to distribute those -+ combinations without any restriction coming from the use of this -+ file. (The Lesser General Public License restrictions do apply in -+ other respects; for example, they cover modification of the file, -+ and distribution when not linked into a combine executable.) -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -+ MA 02110-1301, USA. */ -+ -+#define _FP_FRAC_DECL_1(X) _FP_W_TYPE X##_f -+#define _FP_FRAC_COPY_1(D,S) (D##_f = S##_f) -+#define _FP_FRAC_SET_1(X,I) (X##_f = I) -+#define _FP_FRAC_HIGH_1(X) (X##_f) -+#define _FP_FRAC_LOW_1(X) (X##_f) -+#define _FP_FRAC_WORD_1(X,w) (X##_f) -+ -+#define _FP_FRAC_ADDI_1(X,I) (X##_f += I) -+#define _FP_FRAC_SLL_1(X,N) \ -+ do { \ -+ if (__builtin_constant_p(N) && (N) == 1) \ -+ X##_f += X##_f; \ -+ else \ -+ X##_f <<= (N); \ -+ } while (0) -+#define _FP_FRAC_SRL_1(X,N) (X##_f >>= N) -+ -+/* Right shift with sticky-lsb. */ -+#define _FP_FRAC_SRST_1(X,S,N,sz) __FP_FRAC_SRST_1(X##_f, S, N, sz) -+#define _FP_FRAC_SRS_1(X,N,sz) __FP_FRAC_SRS_1(X##_f, N, sz) -+ -+#define __FP_FRAC_SRST_1(X,S,N,sz) \ -+do { \ -+ S = (__builtin_constant_p(N) && (N) == 1 \ -+ ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0); \ -+ X = X >> (N); \ -+} while (0) -+ -+#define __FP_FRAC_SRS_1(X,N,sz) \ -+ (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1 \ -+ ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0))) -+ -+#define _FP_FRAC_ADD_1(R,X,Y) (R##_f = X##_f + Y##_f) -+#define _FP_FRAC_SUB_1(R,X,Y) (R##_f = X##_f - Y##_f) -+#define _FP_FRAC_DEC_1(X,Y) (X##_f -= Y##_f) -+#define _FP_FRAC_CLZ_1(z, X) __FP_CLZ(z, X##_f) -+ -+/* Predicates */ -+#define _FP_FRAC_NEGP_1(X) ((_FP_WS_TYPE)X##_f < 0) -+#define _FP_FRAC_ZEROP_1(X) (X##_f == 0) -+#define _FP_FRAC_OVERP_1(fs,X) (X##_f & _FP_OVERFLOW_##fs) -+#define _FP_FRAC_CLEAR_OVERP_1(fs,X) (X##_f &= ~_FP_OVERFLOW_##fs) -+#define _FP_FRAC_EQ_1(X, Y) (X##_f == Y##_f) -+#define _FP_FRAC_GE_1(X, Y) (X##_f >= Y##_f) -+#define _FP_FRAC_GT_1(X, Y) (X##_f > Y##_f) -+ -+#define _FP_ZEROFRAC_1 0 -+#define _FP_MINFRAC_1 1 -+#define _FP_MAXFRAC_1 (~(_FP_WS_TYPE)0) -+ -+/* -+ * Unpack the raw bits of a native fp value. Do not classify or -+ * normalize the data. -+ */ -+ -+#define _FP_UNPACK_RAW_1(fs, X, val) \ -+ do { \ -+ union _FP_UNION_##fs _flo; _flo.flt = (val); \ -+ \ -+ X##_f = _flo.bits.frac; \ -+ X##_e = _flo.bits.exp; \ -+ X##_s = _flo.bits.sign; \ -+ } while (0) -+ -+#define _FP_UNPACK_RAW_1_P(fs, X, val) \ -+ do { \ -+ union _FP_UNION_##fs *_flo = \ -+ (union _FP_UNION_##fs *)(val); \ -+ \ -+ X##_f = _flo->bits.frac; \ -+ X##_e = _flo->bits.exp; \ -+ X##_s = _flo->bits.sign; \ -+ } while (0) -+ -+/* -+ * Repack the raw bits of a native fp value. -+ */ -+ -+#define _FP_PACK_RAW_1(fs, val, X) \ -+ do { \ -+ union _FP_UNION_##fs _flo; \ -+ \ -+ _flo.bits.frac = X##_f; \ -+ _flo.bits.exp = X##_e; \ -+ _flo.bits.sign = X##_s; \ -+ \ -+ (val) = _flo.flt; \ -+ } while (0) -+ -+#define _FP_PACK_RAW_1_P(fs, val, X) \ -+ do { \ -+ union _FP_UNION_##fs *_flo = \ -+ (union _FP_UNION_##fs *)(val); \ -+ \ -+ _flo->bits.frac = X##_f; \ -+ _flo->bits.exp = X##_e; \ -+ _flo->bits.sign = X##_s; \ -+ } while (0) -+ -+ -+/* -+ * Multiplication algorithms: -+ */ -+ -+/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the -+ multiplication immediately. */ -+ -+#define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y) \ -+ do { \ -+ R##_f = X##_f * Y##_f; \ -+ /* Normalize since we know where the msb of the multiplicands \ -+ were (bit B), we know that the msb of the of the product is \ -+ at either 2B or 2B-1. */ \ -+ _FP_FRAC_SRS_1(R, wfracbits-1, 2*wfracbits); \ -+ } while (0) -+ -+/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ -+ -+#define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit) \ -+ do { \ -+ _FP_W_TYPE _Z_f0, _Z_f1; \ -+ doit(_Z_f1, _Z_f0, X##_f, Y##_f); \ -+ /* Normalize since we know where the msb of the multiplicands \ -+ were (bit B), we know that the msb of the of the product is \ -+ at either 2B or 2B-1. */ \ -+ _FP_FRAC_SRS_2(_Z, wfracbits-1, 2*wfracbits); \ -+ R##_f = _Z_f0; \ -+ } while (0) -+ -+/* Finally, a simple widening multiply algorithm. What fun! */ -+ -+#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y) \ -+ do { \ -+ _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1; \ -+ \ -+ /* split the words in half */ \ -+ _xh = X##_f >> (_FP_W_TYPE_SIZE/2); \ -+ _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ -+ _yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \ -+ _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ -+ \ -+ /* multiply the pieces */ \ -+ _z_f0 = _xl * _yl; \ -+ _a_f0 = _xh * _yl; \ -+ _a_f1 = _xl * _yh; \ -+ _z_f1 = _xh * _yh; \ -+ \ -+ /* reassemble into two full words */ \ -+ if ((_a_f0 += _a_f1) < _a_f1) \ -+ _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2); \ -+ _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2); \ -+ _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2); \ -+ _FP_FRAC_ADD_2(_z, _z, _a); \ -+ \ -+ /* normalize */ \ -+ _FP_FRAC_SRS_2(_z, wfracbits - 1, 2*wfracbits); \ -+ R##_f = _z_f0; \ -+ } while (0) -+ -+ -+/* -+ * Division algorithms: -+ */ -+ -+/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the -+ division immediately. Give this macro either _FP_DIV_HELP_imm for -+ C primitives or _FP_DIV_HELP_ldiv for the ISO function. Which you -+ choose will depend on what the compiler does with divrem4. */ -+ -+#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \ -+ do { \ -+ _FP_W_TYPE _q, _r; \ -+ X##_f <<= (X##_f < Y##_f \ -+ ? R##_e--, _FP_WFRACBITS_##fs \ -+ : _FP_WFRACBITS_##fs - 1); \ -+ doit(_q, _r, X##_f, Y##_f); \ -+ R##_f = _q | (_r != 0); \ -+ } while (0) -+ -+/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd -+ that may be useful in this situation. This first is for a primitive -+ that requires normalization, the second for one that does not. Look -+ for UDIV_NEEDS_NORMALIZATION to tell which your machine needs. */ -+ -+#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y) \ -+ do { \ -+ _FP_W_TYPE _nh, _nl, _q, _r, _y; \ -+ \ -+ /* Normalize Y -- i.e. make the most significant bit set. */ \ -+ _y = Y##_f << _FP_WFRACXBITS_##fs; \ -+ \ -+ /* Shift X op correspondingly high, that is, up one full word. */ \ -+ if (X##_f < Y##_f) \ -+ { \ -+ R##_e--; \ -+ _nl = 0; \ -+ _nh = X##_f; \ -+ } \ -+ else \ -+ { \ -+ _nl = X##_f << (_FP_W_TYPE_SIZE - 1); \ -+ _nh = X##_f >> 1; \ -+ } \ -+ \ -+ udiv_qrnnd(_q, _r, _nh, _nl, _y); \ -+ R##_f = _q | (_r != 0); \ -+ } while (0) -+ -+#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y) \ -+ do { \ -+ _FP_W_TYPE _nh, _nl, _q, _r; \ -+ if (X##_f < Y##_f) \ -+ { \ -+ R##_e--; \ -+ _nl = X##_f << _FP_WFRACBITS_##fs; \ -+ _nh = X##_f >> _FP_WFRACXBITS_##fs; \ -+ } \ -+ else \ -+ { \ -+ _nl = X##_f << (_FP_WFRACBITS_##fs - 1); \ -+ _nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \ -+ } \ -+ udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \ -+ R##_f = _q | (_r != 0); \ -+ } while (0) -+ -+ -+/* -+ * Square root algorithms: -+ * We have just one right now, maybe Newton approximation -+ * should be added for those machines where division is fast. -+ */ -+ -+#define _FP_SQRT_MEAT_1(R, S, T, X, q) \ -+ do { \ -+ while (q != _FP_WORK_ROUND) \ -+ { \ -+ T##_f = S##_f + q; \ -+ if (T##_f <= X##_f) \ -+ { \ -+ S##_f = T##_f + q; \ -+ X##_f -= T##_f; \ -+ R##_f += q; \ -+ } \ -+ _FP_FRAC_SLL_1(X, 1); \ -+ q >>= 1; \ -+ } \ -+ if (X##_f) \ -+ { \ -+ if (S##_f < X##_f) \ -+ R##_f |= _FP_WORK_ROUND; \ -+ R##_f |= _FP_WORK_STICKY; \ -+ } \ -+ } while (0) -+ -+/* -+ * Assembly/disassembly for converting to/from integral types. -+ * No shifting or overflow handled here. -+ */ -+ -+#define _FP_FRAC_ASSEMBLE_1(r, X, rsize) (r = X##_f) -+#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize) (X##_f = r) -+ -+ -+/* -+ * Convert FP values between word sizes -+ */ -+ -+#define _FP_FRAC_COPY_1_1(D, S) (D##_f = S##_f) -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-2.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-2.h ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-2.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-2.h 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,617 @@ -+/* Software floating-point emulation. -+ Basic two-word fraction declaration and manipulation. -+ Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com), -+ Jakub Jelinek (jj@ultra.linux.cz), -+ David S. Miller (davem@redhat.com) and -+ Peter Maydell (pmaydell@chiark.greenend.org.uk). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ In addition to the permissions in the GNU Lesser General Public -+ License, the Free Software Foundation gives you unlimited -+ permission to link the compiled version of this file into -+ combinations with other programs, and to distribute those -+ combinations without any restriction coming from the use of this -+ file. (The Lesser General Public License restrictions do apply in -+ other respects; for example, they cover modification of the file, -+ and distribution when not linked into a combine executable.) -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -+ MA 02110-1301, USA. */ -+ -+#define _FP_FRAC_DECL_2(X) _FP_W_TYPE X##_f0, X##_f1 -+#define _FP_FRAC_COPY_2(D,S) (D##_f0 = S##_f0, D##_f1 = S##_f1) -+#define _FP_FRAC_SET_2(X,I) __FP_FRAC_SET_2(X, I) -+#define _FP_FRAC_HIGH_2(X) (X##_f1) -+#define _FP_FRAC_LOW_2(X) (X##_f0) -+#define _FP_FRAC_WORD_2(X,w) (X##_f##w) -+ -+#define _FP_FRAC_SLL_2(X,N) \ -+(void)(((N) < _FP_W_TYPE_SIZE) \ -+ ? ({ \ -+ if (__builtin_constant_p(N) && (N) == 1) \ -+ { \ -+ X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0); \ -+ X##_f0 += X##_f0; \ -+ } \ -+ else \ -+ { \ -+ X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \ -+ X##_f0 <<= (N); \ -+ } \ -+ 0; \ -+ }) \ -+ : ({ \ -+ X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE); \ -+ X##_f0 = 0; \ -+ })) -+ -+ -+#define _FP_FRAC_SRL_2(X,N) \ -+(void)(((N) < _FP_W_TYPE_SIZE) \ -+ ? ({ \ -+ X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \ -+ X##_f1 >>= (N); \ -+ }) \ -+ : ({ \ -+ X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE); \ -+ X##_f1 = 0; \ -+ })) -+ -+/* Right shift with sticky-lsb. */ -+#define _FP_FRAC_SRST_2(X,S, N,sz) \ -+(void)(((N) < _FP_W_TYPE_SIZE) \ -+ ? ({ \ -+ S = (__builtin_constant_p(N) && (N) == 1 \ -+ ? X##_f0 & 1 \ -+ : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0); \ -+ X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N)); \ -+ X##_f1 >>= (N); \ -+ }) \ -+ : ({ \ -+ S = ((((N) == _FP_W_TYPE_SIZE \ -+ ? 0 \ -+ : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ -+ | X##_f0) != 0); \ -+ X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE)); \ -+ X##_f1 = 0; \ -+ })) -+ -+#define _FP_FRAC_SRS_2(X,N,sz) \ -+(void)(((N) < _FP_W_TYPE_SIZE) \ -+ ? ({ \ -+ X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) | \ -+ (__builtin_constant_p(N) && (N) == 1 \ -+ ? X##_f0 & 1 \ -+ : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0)); \ -+ X##_f1 >>= (N); \ -+ }) \ -+ : ({ \ -+ X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) | \ -+ ((((N) == _FP_W_TYPE_SIZE \ -+ ? 0 \ -+ : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ -+ | X##_f0) != 0)); \ -+ X##_f1 = 0; \ -+ })) -+ -+#define _FP_FRAC_ADDI_2(X,I) \ -+ __FP_FRAC_ADDI_2(X##_f1, X##_f0, I) -+ -+#define _FP_FRAC_ADD_2(R,X,Y) \ -+ __FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0) -+ -+#define _FP_FRAC_SUB_2(R,X,Y) \ -+ __FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0) -+ -+#define _FP_FRAC_DEC_2(X,Y) \ -+ __FP_FRAC_DEC_2(X##_f1, X##_f0, Y##_f1, Y##_f0) -+ -+#define _FP_FRAC_CLZ_2(R,X) \ -+ do { \ -+ if (X##_f1) \ -+ __FP_CLZ(R,X##_f1); \ -+ else \ -+ { \ -+ __FP_CLZ(R,X##_f0); \ -+ R += _FP_W_TYPE_SIZE; \ -+ } \ -+ } while(0) -+ -+/* Predicates */ -+#define _FP_FRAC_NEGP_2(X) ((_FP_WS_TYPE)X##_f1 < 0) -+#define _FP_FRAC_ZEROP_2(X) ((X##_f1 | X##_f0) == 0) -+#define _FP_FRAC_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs) -+#define _FP_FRAC_CLEAR_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs) -+#define _FP_FRAC_EQ_2(X, Y) (X##_f1 == Y##_f1 && X##_f0 == Y##_f0) -+#define _FP_FRAC_GT_2(X, Y) \ -+ (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0)) -+#define _FP_FRAC_GE_2(X, Y) \ -+ (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0)) -+ -+#define _FP_ZEROFRAC_2 0, 0 -+#define _FP_MINFRAC_2 0, 1 -+#define _FP_MAXFRAC_2 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0) -+ -+/* -+ * Internals -+ */ -+ -+#define __FP_FRAC_SET_2(X,I1,I0) (X##_f0 = I0, X##_f1 = I1) -+ -+#define __FP_CLZ_2(R, xh, xl) \ -+ do { \ -+ if (xh) \ -+ __FP_CLZ(R,xh); \ -+ else \ -+ { \ -+ __FP_CLZ(R,xl); \ -+ R += _FP_W_TYPE_SIZE; \ -+ } \ -+ } while(0) -+ -+#if 0 -+ -+#ifndef __FP_FRAC_ADDI_2 -+#define __FP_FRAC_ADDI_2(xh, xl, i) \ -+ (xh += ((xl += i) < i)) -+#endif -+#ifndef __FP_FRAC_ADD_2 -+#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \ -+ (rh = xh + yh + ((rl = xl + yl) < xl)) -+#endif -+#ifndef __FP_FRAC_SUB_2 -+#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \ -+ (rh = xh - yh - ((rl = xl - yl) > xl)) -+#endif -+#ifndef __FP_FRAC_DEC_2 -+#define __FP_FRAC_DEC_2(xh, xl, yh, yl) \ -+ do { \ -+ UWtype _t = xl; \ -+ xh -= yh + ((xl -= yl) > _t); \ -+ } while (0) -+#endif -+ -+#else -+ -+#undef __FP_FRAC_ADDI_2 -+#define __FP_FRAC_ADDI_2(xh, xl, i) add_ssaaaa(xh, xl, xh, xl, 0, i) -+#undef __FP_FRAC_ADD_2 -+#define __FP_FRAC_ADD_2 add_ssaaaa -+#undef __FP_FRAC_SUB_2 -+#define __FP_FRAC_SUB_2 sub_ddmmss -+#undef __FP_FRAC_DEC_2 -+#define __FP_FRAC_DEC_2(xh, xl, yh, yl) sub_ddmmss(xh, xl, xh, xl, yh, yl) -+ -+#endif -+ -+/* -+ * Unpack the raw bits of a native fp value. Do not classify or -+ * normalize the data. -+ */ -+ -+#define _FP_UNPACK_RAW_2(fs, X, val) \ -+ do { \ -+ union _FP_UNION_##fs _flo; _flo.flt = (val); \ -+ \ -+ X##_f0 = _flo.bits.frac0; \ -+ X##_f1 = _flo.bits.frac1; \ -+ X##_e = _flo.bits.exp; \ -+ X##_s = _flo.bits.sign; \ -+ } while (0) -+ -+#define _FP_UNPACK_RAW_2_P(fs, X, val) \ -+ do { \ -+ union _FP_UNION_##fs *_flo = \ -+ (union _FP_UNION_##fs *)(val); \ -+ \ -+ X##_f0 = _flo->bits.frac0; \ -+ X##_f1 = _flo->bits.frac1; \ -+ X##_e = _flo->bits.exp; \ -+ X##_s = _flo->bits.sign; \ -+ } while (0) -+ -+ -+/* -+ * Repack the raw bits of a native fp value. -+ */ -+ -+#define _FP_PACK_RAW_2(fs, val, X) \ -+ do { \ -+ union _FP_UNION_##fs _flo; \ -+ \ -+ _flo.bits.frac0 = X##_f0; \ -+ _flo.bits.frac1 = X##_f1; \ -+ _flo.bits.exp = X##_e; \ -+ _flo.bits.sign = X##_s; \ -+ \ -+ (val) = _flo.flt; \ -+ } while (0) -+ -+#define _FP_PACK_RAW_2_P(fs, val, X) \ -+ do { \ -+ union _FP_UNION_##fs *_flo = \ -+ (union _FP_UNION_##fs *)(val); \ -+ \ -+ _flo->bits.frac0 = X##_f0; \ -+ _flo->bits.frac1 = X##_f1; \ -+ _flo->bits.exp = X##_e; \ -+ _flo->bits.sign = X##_s; \ -+ } while (0) -+ -+ -+/* -+ * Multiplication algorithms: -+ */ -+ -+/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ -+ -+#define _FP_MUL_MEAT_2_wide(wfracbits, R, X, Y, doit) \ -+ do { \ -+ _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ -+ \ -+ doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \ -+ doit(_b_f1, _b_f0, X##_f0, Y##_f1); \ -+ doit(_c_f1, _c_f0, X##_f1, Y##_f0); \ -+ doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1); \ -+ \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ -+ _FP_FRAC_WORD_4(_z,1), 0, _b_f1, _b_f0, \ -+ _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ -+ _FP_FRAC_WORD_4(_z,1)); \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ -+ _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0, \ -+ _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ -+ _FP_FRAC_WORD_4(_z,1)); \ -+ \ -+ /* Normalize since we know where the msb of the multiplicands \ -+ were (bit B), we know that the msb of the of the product is \ -+ at either 2B or 2B-1. */ \ -+ _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ -+ R##_f0 = _FP_FRAC_WORD_4(_z,0); \ -+ R##_f1 = _FP_FRAC_WORD_4(_z,1); \ -+ } while (0) -+ -+/* Given a 1W * 1W => 2W primitive, do the extended multiplication. -+ Do only 3 multiplications instead of four. This one is for machines -+ where multiplication is much more expensive than subtraction. */ -+ -+#define _FP_MUL_MEAT_2_wide_3mul(wfracbits, R, X, Y, doit) \ -+ do { \ -+ _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ -+ _FP_W_TYPE _d; \ -+ int _c1, _c2; \ -+ \ -+ _b_f0 = X##_f0 + X##_f1; \ -+ _c1 = _b_f0 < X##_f0; \ -+ _b_f1 = Y##_f0 + Y##_f1; \ -+ _c2 = _b_f1 < Y##_f0; \ -+ doit(_d, _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \ -+ doit(_FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1), _b_f0, _b_f1); \ -+ doit(_c_f1, _c_f0, X##_f1, Y##_f1); \ -+ \ -+ _b_f0 &= -_c2; \ -+ _b_f1 &= -_c1; \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ -+ _FP_FRAC_WORD_4(_z,1), (_c1 & _c2), 0, _d, \ -+ 0, _FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1)); \ -+ __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ -+ _b_f0); \ -+ __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ -+ _b_f1); \ -+ __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ -+ _FP_FRAC_WORD_4(_z,1), \ -+ 0, _d, _FP_FRAC_WORD_4(_z,0)); \ -+ __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ -+ _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0); \ -+ __FP_FRAC_ADD_2(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), \ -+ _c_f1, _c_f0, \ -+ _FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2)); \ -+ \ -+ /* Normalize since we know where the msb of the multiplicands \ -+ were (bit B), we know that the msb of the of the product is \ -+ at either 2B or 2B-1. */ \ -+ _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ -+ R##_f0 = _FP_FRAC_WORD_4(_z,0); \ -+ R##_f1 = _FP_FRAC_WORD_4(_z,1); \ -+ } while (0) -+ -+#define _FP_MUL_MEAT_2_gmp(wfracbits, R, X, Y) \ -+ do { \ -+ _FP_FRAC_DECL_4(_z); \ -+ _FP_W_TYPE _x[2], _y[2]; \ -+ _x[0] = X##_f0; _x[1] = X##_f1; \ -+ _y[0] = Y##_f0; _y[1] = Y##_f1; \ -+ \ -+ mpn_mul_n(_z_f, _x, _y, 2); \ -+ \ -+ /* Normalize since we know where the msb of the multiplicands \ -+ were (bit B), we know that the msb of the of the product is \ -+ at either 2B or 2B-1. */ \ -+ _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ -+ R##_f0 = _z_f[0]; \ -+ R##_f1 = _z_f[1]; \ -+ } while (0) -+ -+/* Do at most 120x120=240 bits multiplication using double floating -+ point multiplication. This is useful if floating point -+ multiplication has much bigger throughput than integer multiply. -+ It is supposed to work for _FP_W_TYPE_SIZE 64 and wfracbits -+ between 106 and 120 only. -+ Caller guarantees that X and Y has (1LLL << (wfracbits - 1)) set. -+ SETFETZ is a macro which will disable all FPU exceptions and set rounding -+ towards zero, RESETFE should optionally reset it back. */ -+ -+#define _FP_MUL_MEAT_2_120_240_double(wfracbits, R, X, Y, setfetz, resetfe) \ -+ do { \ -+ static const double _const[] = { \ -+ /* 2^-24 */ 5.9604644775390625e-08, \ -+ /* 2^-48 */ 3.5527136788005009e-15, \ -+ /* 2^-72 */ 2.1175823681357508e-22, \ -+ /* 2^-96 */ 1.2621774483536189e-29, \ -+ /* 2^28 */ 2.68435456e+08, \ -+ /* 2^4 */ 1.600000e+01, \ -+ /* 2^-20 */ 9.5367431640625e-07, \ -+ /* 2^-44 */ 5.6843418860808015e-14, \ -+ /* 2^-68 */ 3.3881317890172014e-21, \ -+ /* 2^-92 */ 2.0194839173657902e-28, \ -+ /* 2^-116 */ 1.2037062152420224e-35}; \ -+ double _a240, _b240, _c240, _d240, _e240, _f240, \ -+ _g240, _h240, _i240, _j240, _k240; \ -+ union { double d; UDItype i; } _l240, _m240, _n240, _o240, \ -+ _p240, _q240, _r240, _s240; \ -+ UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0; \ -+ \ -+ if (wfracbits < 106 || wfracbits > 120) \ -+ abort(); \ -+ \ -+ setfetz; \ -+ \ -+ _e240 = (double)(long)(X##_f0 & 0xffffff); \ -+ _j240 = (double)(long)(Y##_f0 & 0xffffff); \ -+ _d240 = (double)(long)((X##_f0 >> 24) & 0xffffff); \ -+ _i240 = (double)(long)((Y##_f0 >> 24) & 0xffffff); \ -+ _c240 = (double)(long)(((X##_f1 << 16) & 0xffffff) | (X##_f0 >> 48)); \ -+ _h240 = (double)(long)(((Y##_f1 << 16) & 0xffffff) | (Y##_f0 >> 48)); \ -+ _b240 = (double)(long)((X##_f1 >> 8) & 0xffffff); \ -+ _g240 = (double)(long)((Y##_f1 >> 8) & 0xffffff); \ -+ _a240 = (double)(long)(X##_f1 >> 32); \ -+ _f240 = (double)(long)(Y##_f1 >> 32); \ -+ _e240 *= _const[3]; \ -+ _j240 *= _const[3]; \ -+ _d240 *= _const[2]; \ -+ _i240 *= _const[2]; \ -+ _c240 *= _const[1]; \ -+ _h240 *= _const[1]; \ -+ _b240 *= _const[0]; \ -+ _g240 *= _const[0]; \ -+ _s240.d = _e240*_j240;\ -+ _r240.d = _d240*_j240 + _e240*_i240;\ -+ _q240.d = _c240*_j240 + _d240*_i240 + _e240*_h240;\ -+ _p240.d = _b240*_j240 + _c240*_i240 + _d240*_h240 + _e240*_g240;\ -+ _o240.d = _a240*_j240 + _b240*_i240 + _c240*_h240 + _d240*_g240 + _e240*_f240;\ -+ _n240.d = _a240*_i240 + _b240*_h240 + _c240*_g240 + _d240*_f240; \ -+ _m240.d = _a240*_h240 + _b240*_g240 + _c240*_f240; \ -+ _l240.d = _a240*_g240 + _b240*_f240; \ -+ _k240 = _a240*_f240; \ -+ _r240.d += _s240.d; \ -+ _q240.d += _r240.d; \ -+ _p240.d += _q240.d; \ -+ _o240.d += _p240.d; \ -+ _n240.d += _o240.d; \ -+ _m240.d += _n240.d; \ -+ _l240.d += _m240.d; \ -+ _k240 += _l240.d; \ -+ _s240.d -= ((_const[10]+_s240.d)-_const[10]); \ -+ _r240.d -= ((_const[9]+_r240.d)-_const[9]); \ -+ _q240.d -= ((_const[8]+_q240.d)-_const[8]); \ -+ _p240.d -= ((_const[7]+_p240.d)-_const[7]); \ -+ _o240.d += _const[7]; \ -+ _n240.d += _const[6]; \ -+ _m240.d += _const[5]; \ -+ _l240.d += _const[4]; \ -+ if (_s240.d != 0.0) _y240 = 1; \ -+ if (_r240.d != 0.0) _y240 = 1; \ -+ if (_q240.d != 0.0) _y240 = 1; \ -+ if (_p240.d != 0.0) _y240 = 1; \ -+ _t240 = (DItype)_k240; \ -+ _u240 = _l240.i; \ -+ _v240 = _m240.i; \ -+ _w240 = _n240.i; \ -+ _x240 = _o240.i; \ -+ R##_f1 = (_t240 << (128 - (wfracbits - 1))) \ -+ | ((_u240 & 0xffffff) >> ((wfracbits - 1) - 104)); \ -+ R##_f0 = ((_u240 & 0xffffff) << (168 - (wfracbits - 1))) \ -+ | ((_v240 & 0xffffff) << (144 - (wfracbits - 1))) \ -+ | ((_w240 & 0xffffff) << (120 - (wfracbits - 1))) \ -+ | ((_x240 & 0xffffff) >> ((wfracbits - 1) - 96)) \ -+ | _y240; \ -+ resetfe; \ -+ } while (0) -+ -+/* -+ * Division algorithms: -+ */ -+ -+#define _FP_DIV_MEAT_2_udiv(fs, R, X, Y) \ -+ do { \ -+ _FP_W_TYPE _n_f2, _n_f1, _n_f0, _r_f1, _r_f0, _m_f1, _m_f0; \ -+ if (_FP_FRAC_GT_2(X, Y)) \ -+ { \ -+ _n_f2 = X##_f1 >> 1; \ -+ _n_f1 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1; \ -+ _n_f0 = X##_f0 << (_FP_W_TYPE_SIZE - 1); \ -+ } \ -+ else \ -+ { \ -+ R##_e--; \ -+ _n_f2 = X##_f1; \ -+ _n_f1 = X##_f0; \ -+ _n_f0 = 0; \ -+ } \ -+ \ -+ /* Normalize, i.e. make the most significant bit of the \ -+ denominator set. */ \ -+ _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs); \ -+ \ -+ udiv_qrnnd(R##_f1, _r_f1, _n_f2, _n_f1, Y##_f1); \ -+ umul_ppmm(_m_f1, _m_f0, R##_f1, Y##_f0); \ -+ _r_f0 = _n_f0; \ -+ if (_FP_FRAC_GT_2(_m, _r)) \ -+ { \ -+ R##_f1--; \ -+ _FP_FRAC_ADD_2(_r, Y, _r); \ -+ if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ -+ { \ -+ R##_f1--; \ -+ _FP_FRAC_ADD_2(_r, Y, _r); \ -+ } \ -+ } \ -+ _FP_FRAC_DEC_2(_r, _m); \ -+ \ -+ if (_r_f1 == Y##_f1) \ -+ { \ -+ /* This is a special case, not an optimization \ -+ (_r/Y##_f1 would not fit into UWtype). \ -+ As _r is guaranteed to be < Y, R##_f0 can be either \ -+ (UWtype)-1 or (UWtype)-2. But as we know what kind \ -+ of bits it is (sticky, guard, round), we don't care. \ -+ We also don't care what the reminder is, because the \ -+ guard bit will be set anyway. -jj */ \ -+ R##_f0 = -1; \ -+ } \ -+ else \ -+ { \ -+ udiv_qrnnd(R##_f0, _r_f1, _r_f1, _r_f0, Y##_f1); \ -+ umul_ppmm(_m_f1, _m_f0, R##_f0, Y##_f0); \ -+ _r_f0 = 0; \ -+ if (_FP_FRAC_GT_2(_m, _r)) \ -+ { \ -+ R##_f0--; \ -+ _FP_FRAC_ADD_2(_r, Y, _r); \ -+ if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ -+ { \ -+ R##_f0--; \ -+ _FP_FRAC_ADD_2(_r, Y, _r); \ -+ } \ -+ } \ -+ if (!_FP_FRAC_EQ_2(_r, _m)) \ -+ R##_f0 |= _FP_WORK_STICKY; \ -+ } \ -+ } while (0) -+ -+ -+#define _FP_DIV_MEAT_2_gmp(fs, R, X, Y) \ -+ do { \ -+ _FP_W_TYPE _x[4], _y[2], _z[4]; \ -+ _y[0] = Y##_f0; _y[1] = Y##_f1; \ -+ _x[0] = _x[3] = 0; \ -+ if (_FP_FRAC_GT_2(X, Y)) \ -+ { \ -+ R##_e++; \ -+ _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE) | \ -+ X##_f1 >> (_FP_W_TYPE_SIZE - \ -+ (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE))); \ -+ _x[2] = X##_f1 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE); \ -+ } \ -+ else \ -+ { \ -+ _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE) | \ -+ X##_f1 >> (_FP_W_TYPE_SIZE - \ -+ (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE))); \ -+ _x[2] = X##_f1 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE); \ -+ } \ -+ \ -+ (void) mpn_divrem (_z, 0, _x, 4, _y, 2); \ -+ R##_f1 = _z[1]; \ -+ R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0); \ -+ } while (0) -+ -+ -+/* -+ * Square root algorithms: -+ * We have just one right now, maybe Newton approximation -+ * should be added for those machines where division is fast. -+ */ -+ -+#define _FP_SQRT_MEAT_2(R, S, T, X, q) \ -+ do { \ -+ while (q) \ -+ { \ -+ T##_f1 = S##_f1 + q; \ -+ if (T##_f1 <= X##_f1) \ -+ { \ -+ S##_f1 = T##_f1 + q; \ -+ X##_f1 -= T##_f1; \ -+ R##_f1 += q; \ -+ } \ -+ _FP_FRAC_SLL_2(X, 1); \ -+ q >>= 1; \ -+ } \ -+ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ -+ while (q != _FP_WORK_ROUND) \ -+ { \ -+ T##_f0 = S##_f0 + q; \ -+ T##_f1 = S##_f1; \ -+ if (T##_f1 < X##_f1 || \ -+ (T##_f1 == X##_f1 && T##_f0 <= X##_f0)) \ -+ { \ -+ S##_f0 = T##_f0 + q; \ -+ S##_f1 += (T##_f0 > S##_f0); \ -+ _FP_FRAC_DEC_2(X, T); \ -+ R##_f0 += q; \ -+ } \ -+ _FP_FRAC_SLL_2(X, 1); \ -+ q >>= 1; \ -+ } \ -+ if (X##_f0 | X##_f1) \ -+ { \ -+ if (S##_f1 < X##_f1 || \ -+ (S##_f1 == X##_f1 && S##_f0 < X##_f0)) \ -+ R##_f0 |= _FP_WORK_ROUND; \ -+ R##_f0 |= _FP_WORK_STICKY; \ -+ } \ -+ } while (0) -+ -+ -+/* -+ * Assembly/disassembly for converting to/from integral types. -+ * No shifting or overflow handled here. -+ */ -+ -+#define _FP_FRAC_ASSEMBLE_2(r, X, rsize) \ -+(void)((rsize <= _FP_W_TYPE_SIZE) \ -+ ? ({ r = X##_f0; }) \ -+ : ({ \ -+ r = X##_f1; \ -+ r <<= _FP_W_TYPE_SIZE; \ -+ r += X##_f0; \ -+ })) -+ -+#define _FP_FRAC_DISASSEMBLE_2(X, r, rsize) \ -+ do { \ -+ X##_f0 = r; \ -+ X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ -+ } while (0) -+ -+/* -+ * Convert FP values between word sizes -+ */ -+ -+#define _FP_FRAC_COPY_1_2(D, S) (D##_f = S##_f0) -+ -+#define _FP_FRAC_COPY_2_1(D, S) ((D##_f0 = S##_f), (D##_f1 = 0)) -+ -+#define _FP_FRAC_COPY_2_2(D,S) _FP_FRAC_COPY_2(D,S) -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-4.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-4.h ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-4.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-4.h 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,688 @@ -+/* Software floating-point emulation. -+ Basic four-word fraction declaration and manipulation. -+ Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com), -+ Jakub Jelinek (jj@ultra.linux.cz), -+ David S. Miller (davem@redhat.com) and -+ Peter Maydell (pmaydell@chiark.greenend.org.uk). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ In addition to the permissions in the GNU Lesser General Public -+ License, the Free Software Foundation gives you unlimited -+ permission to link the compiled version of this file into -+ combinations with other programs, and to distribute those -+ combinations without any restriction coming from the use of this -+ file. (The Lesser General Public License restrictions do apply in -+ other respects; for example, they cover modification of the file, -+ and distribution when not linked into a combine executable.) -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -+ MA 02110-1301, USA. */ -+ -+#define _FP_FRAC_DECL_4(X) _FP_W_TYPE X##_f[4] -+#define _FP_FRAC_COPY_4(D,S) \ -+ (D##_f[0] = S##_f[0], D##_f[1] = S##_f[1], \ -+ D##_f[2] = S##_f[2], D##_f[3] = S##_f[3]) -+#define _FP_FRAC_SET_4(X,I) __FP_FRAC_SET_4(X, I) -+#define _FP_FRAC_HIGH_4(X) (X##_f[3]) -+#define _FP_FRAC_LOW_4(X) (X##_f[0]) -+#define _FP_FRAC_WORD_4(X,w) (X##_f[w]) -+ -+#define _FP_FRAC_SLL_4(X,N) \ -+ do { \ -+ _FP_I_TYPE _up, _down, _skip, _i; \ -+ _skip = (N) / _FP_W_TYPE_SIZE; \ -+ _up = (N) % _FP_W_TYPE_SIZE; \ -+ _down = _FP_W_TYPE_SIZE - _up; \ -+ if (!_up) \ -+ for (_i = 3; _i >= _skip; --_i) \ -+ X##_f[_i] = X##_f[_i-_skip]; \ -+ else \ -+ { \ -+ for (_i = 3; _i > _skip; --_i) \ -+ X##_f[_i] = X##_f[_i-_skip] << _up \ -+ | X##_f[_i-_skip-1] >> _down; \ -+ X##_f[_i--] = X##_f[0] << _up; \ -+ } \ -+ for (; _i >= 0; --_i) \ -+ X##_f[_i] = 0; \ -+ } while (0) -+ -+/* This one was broken too */ -+#define _FP_FRAC_SRL_4(X,N) \ -+ do { \ -+ _FP_I_TYPE _up, _down, _skip, _i; \ -+ _skip = (N) / _FP_W_TYPE_SIZE; \ -+ _down = (N) % _FP_W_TYPE_SIZE; \ -+ _up = _FP_W_TYPE_SIZE - _down; \ -+ if (!_down) \ -+ for (_i = 0; _i <= 3-_skip; ++_i) \ -+ X##_f[_i] = X##_f[_i+_skip]; \ -+ else \ -+ { \ -+ for (_i = 0; _i < 3-_skip; ++_i) \ -+ X##_f[_i] = X##_f[_i+_skip] >> _down \ -+ | X##_f[_i+_skip+1] << _up; \ -+ X##_f[_i++] = X##_f[3] >> _down; \ -+ } \ -+ for (; _i < 4; ++_i) \ -+ X##_f[_i] = 0; \ -+ } while (0) -+ -+ -+/* Right shift with sticky-lsb. -+ * What this actually means is that we do a standard right-shift, -+ * but that if any of the bits that fall off the right hand side -+ * were one then we always set the LSbit. -+ */ -+#define _FP_FRAC_SRST_4(X,S,N,size) \ -+ do { \ -+ _FP_I_TYPE _up, _down, _skip, _i; \ -+ _FP_W_TYPE _s; \ -+ _skip = (N) / _FP_W_TYPE_SIZE; \ -+ _down = (N) % _FP_W_TYPE_SIZE; \ -+ _up = _FP_W_TYPE_SIZE - _down; \ -+ for (_s = _i = 0; _i < _skip; ++_i) \ -+ _s |= X##_f[_i]; \ -+ if (!_down) \ -+ for (_i = 0; _i <= 3-_skip; ++_i) \ -+ X##_f[_i] = X##_f[_i+_skip]; \ -+ else \ -+ { \ -+ _s |= X##_f[_i] << _up; \ -+ for (_i = 0; _i < 3-_skip; ++_i) \ -+ X##_f[_i] = X##_f[_i+_skip] >> _down \ -+ | X##_f[_i+_skip+1] << _up; \ -+ X##_f[_i++] = X##_f[3] >> _down; \ -+ } \ -+ for (; _i < 4; ++_i) \ -+ X##_f[_i] = 0; \ -+ S = (_s != 0); \ -+ } while (0) -+ -+#define _FP_FRAC_SRS_4(X,N,size) \ -+ do { \ -+ int _sticky; \ -+ _FP_FRAC_SRST_4(X, _sticky, N, size); \ -+ X##_f[0] |= _sticky; \ -+ } while (0) -+ -+#define _FP_FRAC_ADD_4(R,X,Y) \ -+ __FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \ -+ X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ -+ Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) -+ -+#define _FP_FRAC_SUB_4(R,X,Y) \ -+ __FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \ -+ X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ -+ Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) -+ -+#define _FP_FRAC_DEC_4(X,Y) \ -+ __FP_FRAC_DEC_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ -+ Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) -+ -+#define _FP_FRAC_ADDI_4(X,I) \ -+ __FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I) -+ -+#define _FP_ZEROFRAC_4 0,0,0,0 -+#define _FP_MINFRAC_4 0,0,0,1 -+#define _FP_MAXFRAC_4 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0) -+ -+#define _FP_FRAC_ZEROP_4(X) ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0) -+#define _FP_FRAC_NEGP_4(X) ((_FP_WS_TYPE)X##_f[3] < 0) -+#define _FP_FRAC_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs) -+#define _FP_FRAC_CLEAR_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs) -+ -+#define _FP_FRAC_EQ_4(X,Y) \ -+ (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1] \ -+ && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3]) -+ -+#define _FP_FRAC_GT_4(X,Y) \ -+ (X##_f[3] > Y##_f[3] || \ -+ (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \ -+ (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \ -+ (X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0]) \ -+ )) \ -+ )) \ -+ ) -+ -+#define _FP_FRAC_GE_4(X,Y) \ -+ (X##_f[3] > Y##_f[3] || \ -+ (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \ -+ (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \ -+ (X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0]) \ -+ )) \ -+ )) \ -+ ) -+ -+ -+#define _FP_FRAC_CLZ_4(R,X) \ -+ do { \ -+ if (X##_f[3]) \ -+ { \ -+ __FP_CLZ(R,X##_f[3]); \ -+ } \ -+ else if (X##_f[2]) \ -+ { \ -+ __FP_CLZ(R,X##_f[2]); \ -+ R += _FP_W_TYPE_SIZE; \ -+ } \ -+ else if (X##_f[1]) \ -+ { \ -+ __FP_CLZ(R,X##_f[1]); \ -+ R += _FP_W_TYPE_SIZE*2; \ -+ } \ -+ else \ -+ { \ -+ __FP_CLZ(R,X##_f[0]); \ -+ R += _FP_W_TYPE_SIZE*3; \ -+ } \ -+ } while(0) -+ -+ -+#define _FP_UNPACK_RAW_4(fs, X, val) \ -+ do { \ -+ union _FP_UNION_##fs _flo; _flo.flt = (val); \ -+ X##_f[0] = _flo.bits.frac0; \ -+ X##_f[1] = _flo.bits.frac1; \ -+ X##_f[2] = _flo.bits.frac2; \ -+ X##_f[3] = _flo.bits.frac3; \ -+ X##_e = _flo.bits.exp; \ -+ X##_s = _flo.bits.sign; \ -+ } while (0) -+ -+#define _FP_UNPACK_RAW_4_P(fs, X, val) \ -+ do { \ -+ union _FP_UNION_##fs *_flo = \ -+ (union _FP_UNION_##fs *)(val); \ -+ \ -+ X##_f[0] = _flo->bits.frac0; \ -+ X##_f[1] = _flo->bits.frac1; \ -+ X##_f[2] = _flo->bits.frac2; \ -+ X##_f[3] = _flo->bits.frac3; \ -+ X##_e = _flo->bits.exp; \ -+ X##_s = _flo->bits.sign; \ -+ } while (0) -+ -+#define _FP_PACK_RAW_4(fs, val, X) \ -+ do { \ -+ union _FP_UNION_##fs _flo; \ -+ _flo.bits.frac0 = X##_f[0]; \ -+ _flo.bits.frac1 = X##_f[1]; \ -+ _flo.bits.frac2 = X##_f[2]; \ -+ _flo.bits.frac3 = X##_f[3]; \ -+ _flo.bits.exp = X##_e; \ -+ _flo.bits.sign = X##_s; \ -+ (val) = _flo.flt; \ -+ } while (0) -+ -+#define _FP_PACK_RAW_4_P(fs, val, X) \ -+ do { \ -+ union _FP_UNION_##fs *_flo = \ -+ (union _FP_UNION_##fs *)(val); \ -+ \ -+ _flo->bits.frac0 = X##_f[0]; \ -+ _flo->bits.frac1 = X##_f[1]; \ -+ _flo->bits.frac2 = X##_f[2]; \ -+ _flo->bits.frac3 = X##_f[3]; \ -+ _flo->bits.exp = X##_e; \ -+ _flo->bits.sign = X##_s; \ -+ } while (0) -+ -+/* -+ * Multiplication algorithms: -+ */ -+ -+/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ -+ -+#define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit) \ -+ do { \ -+ _FP_FRAC_DECL_8(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ -+ _FP_FRAC_DECL_2(_d); _FP_FRAC_DECL_2(_e); _FP_FRAC_DECL_2(_f); \ -+ \ -+ doit(_FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0), X##_f[0], Y##_f[0]); \ -+ doit(_b_f1, _b_f0, X##_f[0], Y##_f[1]); \ -+ doit(_c_f1, _c_f0, X##_f[1], Y##_f[0]); \ -+ doit(_d_f1, _d_f0, X##_f[1], Y##_f[1]); \ -+ doit(_e_f1, _e_f0, X##_f[0], Y##_f[2]); \ -+ doit(_f_f1, _f_f0, X##_f[2], Y##_f[0]); \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \ -+ _FP_FRAC_WORD_8(_z,1), 0,_b_f1,_b_f0, \ -+ 0,0,_FP_FRAC_WORD_8(_z,1)); \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \ -+ _FP_FRAC_WORD_8(_z,1), 0,_c_f1,_c_f0, \ -+ _FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \ -+ _FP_FRAC_WORD_8(_z,1)); \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ -+ _FP_FRAC_WORD_8(_z,2), 0,_d_f1,_d_f0, \ -+ 0,_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2)); \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ -+ _FP_FRAC_WORD_8(_z,2), 0,_e_f1,_e_f0, \ -+ _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ -+ _FP_FRAC_WORD_8(_z,2)); \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ -+ _FP_FRAC_WORD_8(_z,2), 0,_f_f1,_f_f0, \ -+ _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ -+ _FP_FRAC_WORD_8(_z,2)); \ -+ doit(_b_f1, _b_f0, X##_f[0], Y##_f[3]); \ -+ doit(_c_f1, _c_f0, X##_f[3], Y##_f[0]); \ -+ doit(_d_f1, _d_f0, X##_f[1], Y##_f[2]); \ -+ doit(_e_f1, _e_f0, X##_f[2], Y##_f[1]); \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ -+ _FP_FRAC_WORD_8(_z,3), 0,_b_f1,_b_f0, \ -+ 0,_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3)); \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ -+ _FP_FRAC_WORD_8(_z,3), 0,_c_f1,_c_f0, \ -+ _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ -+ _FP_FRAC_WORD_8(_z,3)); \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ -+ _FP_FRAC_WORD_8(_z,3), 0,_d_f1,_d_f0, \ -+ _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ -+ _FP_FRAC_WORD_8(_z,3)); \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ -+ _FP_FRAC_WORD_8(_z,3), 0,_e_f1,_e_f0, \ -+ _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ -+ _FP_FRAC_WORD_8(_z,3)); \ -+ doit(_b_f1, _b_f0, X##_f[2], Y##_f[2]); \ -+ doit(_c_f1, _c_f0, X##_f[1], Y##_f[3]); \ -+ doit(_d_f1, _d_f0, X##_f[3], Y##_f[1]); \ -+ doit(_e_f1, _e_f0, X##_f[2], Y##_f[3]); \ -+ doit(_f_f1, _f_f0, X##_f[3], Y##_f[2]); \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ -+ _FP_FRAC_WORD_8(_z,4), 0,_b_f1,_b_f0, \ -+ 0,_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4)); \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ -+ _FP_FRAC_WORD_8(_z,4), 0,_c_f1,_c_f0, \ -+ _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ -+ _FP_FRAC_WORD_8(_z,4)); \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ -+ _FP_FRAC_WORD_8(_z,4), 0,_d_f1,_d_f0, \ -+ _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ -+ _FP_FRAC_WORD_8(_z,4)); \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ -+ _FP_FRAC_WORD_8(_z,5), 0,_e_f1,_e_f0, \ -+ 0,_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5)); \ -+ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ -+ _FP_FRAC_WORD_8(_z,5), 0,_f_f1,_f_f0, \ -+ _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ -+ _FP_FRAC_WORD_8(_z,5)); \ -+ doit(_b_f1, _b_f0, X##_f[3], Y##_f[3]); \ -+ __FP_FRAC_ADD_2(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ -+ _b_f1,_b_f0, \ -+ _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6)); \ -+ \ -+ /* Normalize since we know where the msb of the multiplicands \ -+ were (bit B), we know that the msb of the of the product is \ -+ at either 2B or 2B-1. */ \ -+ _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \ -+ __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \ -+ _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \ -+ } while (0) -+ -+#define _FP_MUL_MEAT_4_gmp(wfracbits, R, X, Y) \ -+ do { \ -+ _FP_FRAC_DECL_8(_z); \ -+ \ -+ mpn_mul_n(_z_f, _x_f, _y_f, 4); \ -+ \ -+ /* Normalize since we know where the msb of the multiplicands \ -+ were (bit B), we know that the msb of the of the product is \ -+ at either 2B or 2B-1. */ \ -+ _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \ -+ __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \ -+ _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \ -+ } while (0) -+ -+/* -+ * Helper utility for _FP_DIV_MEAT_4_udiv: -+ * pppp = m * nnn -+ */ -+#define umul_ppppmnnn(p3,p2,p1,p0,m,n2,n1,n0) \ -+ do { \ -+ UWtype _t; \ -+ umul_ppmm(p1,p0,m,n0); \ -+ umul_ppmm(p2,_t,m,n1); \ -+ __FP_FRAC_ADDI_2(p2,p1,_t); \ -+ umul_ppmm(p3,_t,m,n2); \ -+ __FP_FRAC_ADDI_2(p3,p2,_t); \ -+ } while (0) -+ -+/* -+ * Division algorithms: -+ */ -+ -+#define _FP_DIV_MEAT_4_udiv(fs, R, X, Y) \ -+ do { \ -+ int _i; \ -+ _FP_FRAC_DECL_4(_n); _FP_FRAC_DECL_4(_m); \ -+ _FP_FRAC_SET_4(_n, _FP_ZEROFRAC_4); \ -+ if (_FP_FRAC_GT_4(X, Y)) \ -+ { \ -+ _n_f[3] = X##_f[0] << (_FP_W_TYPE_SIZE - 1); \ -+ _FP_FRAC_SRL_4(X, 1); \ -+ } \ -+ else \ -+ R##_e--; \ -+ \ -+ /* Normalize, i.e. make the most significant bit of the \ -+ denominator set. */ \ -+ _FP_FRAC_SLL_4(Y, _FP_WFRACXBITS_##fs); \ -+ \ -+ for (_i = 3; ; _i--) \ -+ { \ -+ if (X##_f[3] == Y##_f[3]) \ -+ { \ -+ /* This is a special case, not an optimization \ -+ (X##_f[3]/Y##_f[3] would not fit into UWtype). \ -+ As X## is guaranteed to be < Y, R##_f[_i] can be either \ -+ (UWtype)-1 or (UWtype)-2. */ \ -+ R##_f[_i] = -1; \ -+ if (!_i) \ -+ break; \ -+ __FP_FRAC_SUB_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ -+ Y##_f[2], Y##_f[1], Y##_f[0], 0, \ -+ X##_f[2], X##_f[1], X##_f[0], _n_f[_i]); \ -+ _FP_FRAC_SUB_4(X, Y, X); \ -+ if (X##_f[3] > Y##_f[3]) \ -+ { \ -+ R##_f[_i] = -2; \ -+ _FP_FRAC_ADD_4(X, Y, X); \ -+ } \ -+ } \ -+ else \ -+ { \ -+ udiv_qrnnd(R##_f[_i], X##_f[3], X##_f[3], X##_f[2], Y##_f[3]); \ -+ umul_ppppmnnn(_m_f[3], _m_f[2], _m_f[1], _m_f[0], \ -+ R##_f[_i], Y##_f[2], Y##_f[1], Y##_f[0]); \ -+ X##_f[2] = X##_f[1]; \ -+ X##_f[1] = X##_f[0]; \ -+ X##_f[0] = _n_f[_i]; \ -+ if (_FP_FRAC_GT_4(_m, X)) \ -+ { \ -+ R##_f[_i]--; \ -+ _FP_FRAC_ADD_4(X, Y, X); \ -+ if (_FP_FRAC_GE_4(X, Y) && _FP_FRAC_GT_4(_m, X)) \ -+ { \ -+ R##_f[_i]--; \ -+ _FP_FRAC_ADD_4(X, Y, X); \ -+ } \ -+ } \ -+ _FP_FRAC_DEC_4(X, _m); \ -+ if (!_i) \ -+ { \ -+ if (!_FP_FRAC_EQ_4(X, _m)) \ -+ R##_f[0] |= _FP_WORK_STICKY; \ -+ break; \ -+ } \ -+ } \ -+ } \ -+ } while (0) -+ -+ -+/* -+ * Square root algorithms: -+ * We have just one right now, maybe Newton approximation -+ * should be added for those machines where division is fast. -+ */ -+ -+#define _FP_SQRT_MEAT_4(R, S, T, X, q) \ -+ do { \ -+ while (q) \ -+ { \ -+ T##_f[3] = S##_f[3] + q; \ -+ if (T##_f[3] <= X##_f[3]) \ -+ { \ -+ S##_f[3] = T##_f[3] + q; \ -+ X##_f[3] -= T##_f[3]; \ -+ R##_f[3] += q; \ -+ } \ -+ _FP_FRAC_SLL_4(X, 1); \ -+ q >>= 1; \ -+ } \ -+ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ -+ while (q) \ -+ { \ -+ T##_f[2] = S##_f[2] + q; \ -+ T##_f[3] = S##_f[3]; \ -+ if (T##_f[3] < X##_f[3] || \ -+ (T##_f[3] == X##_f[3] && T##_f[2] <= X##_f[2])) \ -+ { \ -+ S##_f[2] = T##_f[2] + q; \ -+ S##_f[3] += (T##_f[2] > S##_f[2]); \ -+ __FP_FRAC_DEC_2(X##_f[3], X##_f[2], \ -+ T##_f[3], T##_f[2]); \ -+ R##_f[2] += q; \ -+ } \ -+ _FP_FRAC_SLL_4(X, 1); \ -+ q >>= 1; \ -+ } \ -+ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ -+ while (q) \ -+ { \ -+ T##_f[1] = S##_f[1] + q; \ -+ T##_f[2] = S##_f[2]; \ -+ T##_f[3] = S##_f[3]; \ -+ if (T##_f[3] < X##_f[3] || \ -+ (T##_f[3] == X##_f[3] && (T##_f[2] < X##_f[2] || \ -+ (T##_f[2] == X##_f[2] && T##_f[1] <= X##_f[1])))) \ -+ { \ -+ S##_f[1] = T##_f[1] + q; \ -+ S##_f[2] += (T##_f[1] > S##_f[1]); \ -+ S##_f[3] += (T##_f[2] > S##_f[2]); \ -+ __FP_FRAC_DEC_3(X##_f[3], X##_f[2], X##_f[1], \ -+ T##_f[3], T##_f[2], T##_f[1]); \ -+ R##_f[1] += q; \ -+ } \ -+ _FP_FRAC_SLL_4(X, 1); \ -+ q >>= 1; \ -+ } \ -+ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ -+ while (q != _FP_WORK_ROUND) \ -+ { \ -+ T##_f[0] = S##_f[0] + q; \ -+ T##_f[1] = S##_f[1]; \ -+ T##_f[2] = S##_f[2]; \ -+ T##_f[3] = S##_f[3]; \ -+ if (_FP_FRAC_GE_4(X,T)) \ -+ { \ -+ S##_f[0] = T##_f[0] + q; \ -+ S##_f[1] += (T##_f[0] > S##_f[0]); \ -+ S##_f[2] += (T##_f[1] > S##_f[1]); \ -+ S##_f[3] += (T##_f[2] > S##_f[2]); \ -+ _FP_FRAC_DEC_4(X, T); \ -+ R##_f[0] += q; \ -+ } \ -+ _FP_FRAC_SLL_4(X, 1); \ -+ q >>= 1; \ -+ } \ -+ if (!_FP_FRAC_ZEROP_4(X)) \ -+ { \ -+ if (_FP_FRAC_GT_4(X,S)) \ -+ R##_f[0] |= _FP_WORK_ROUND; \ -+ R##_f[0] |= _FP_WORK_STICKY; \ -+ } \ -+ } while (0) -+ -+ -+/* -+ * Internals -+ */ -+ -+#define __FP_FRAC_SET_4(X,I3,I2,I1,I0) \ -+ (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0) -+ -+#ifndef __FP_FRAC_ADD_3 -+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ -+ do { \ -+ _FP_W_TYPE _c1, _c2; \ -+ r0 = x0 + y0; \ -+ _c1 = r0 < x0; \ -+ r1 = x1 + y1; \ -+ _c2 = r1 < x1; \ -+ r1 += _c1; \ -+ _c2 |= r1 < _c1; \ -+ r2 = x2 + y2 + _c2; \ -+ } while (0) -+#endif -+ -+#ifndef __FP_FRAC_ADD_4 -+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ -+ do { \ -+ _FP_W_TYPE _c1, _c2, _c3; \ -+ r0 = x0 + y0; \ -+ _c1 = r0 < x0; \ -+ r1 = x1 + y1; \ -+ _c2 = r1 < x1; \ -+ r1 += _c1; \ -+ _c2 |= r1 < _c1; \ -+ r2 = x2 + y2; \ -+ _c3 = r2 < x2; \ -+ r2 += _c2; \ -+ _c3 |= r2 < _c2; \ -+ r3 = x3 + y3 + _c3; \ -+ } while (0) -+#endif -+ -+#ifndef __FP_FRAC_SUB_3 -+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ -+ do { \ -+ _FP_W_TYPE _c1, _c2; \ -+ r0 = x0 - y0; \ -+ _c1 = r0 > x0; \ -+ r1 = x1 - y1; \ -+ _c2 = r1 > x1; \ -+ r1 -= _c1; \ -+ _c2 |= _c1 && (y1 == x1); \ -+ r2 = x2 - y2 - _c2; \ -+ } while (0) -+#endif -+ -+#ifndef __FP_FRAC_SUB_4 -+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ -+ do { \ -+ _FP_W_TYPE _c1, _c2, _c3; \ -+ r0 = x0 - y0; \ -+ _c1 = r0 > x0; \ -+ r1 = x1 - y1; \ -+ _c2 = r1 > x1; \ -+ r1 -= _c1; \ -+ _c2 |= _c1 && (y1 == x1); \ -+ r2 = x2 - y2; \ -+ _c3 = r2 > x2; \ -+ r2 -= _c2; \ -+ _c3 |= _c2 && (y2 == x2); \ -+ r3 = x3 - y3 - _c3; \ -+ } while (0) -+#endif -+ -+#ifndef __FP_FRAC_DEC_3 -+#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) \ -+ do { \ -+ UWtype _t0, _t1, _t2; \ -+ _t0 = x0, _t1 = x1, _t2 = x2; \ -+ __FP_FRAC_SUB_3 (x2, x1, x0, _t2, _t1, _t0, y2, y1, y0); \ -+ } while (0) -+#endif -+ -+#ifndef __FP_FRAC_DEC_4 -+#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) \ -+ do { \ -+ UWtype _t0, _t1, _t2, _t3; \ -+ _t0 = x0, _t1 = x1, _t2 = x2, _t3 = x3; \ -+ __FP_FRAC_SUB_4 (x3,x2,x1,x0,_t3,_t2,_t1,_t0, y3,y2,y1,y0); \ -+ } while (0) -+#endif -+ -+#ifndef __FP_FRAC_ADDI_4 -+#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \ -+ do { \ -+ UWtype _t; \ -+ _t = ((x0 += i) < i); \ -+ x1 += _t; _t = (x1 < _t); \ -+ x2 += _t; _t = (x2 < _t); \ -+ x3 += _t; \ -+ } while (0) -+#endif -+ -+/* Convert FP values between word sizes. This appears to be more -+ * complicated than I'd have expected it to be, so these might be -+ * wrong... These macros are in any case somewhat bogus because they -+ * use information about what various FRAC_n variables look like -+ * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do -+ * the ones in op-2.h and op-1.h. -+ */ -+#define _FP_FRAC_COPY_1_4(D, S) (D##_f = S##_f[0]) -+ -+#define _FP_FRAC_COPY_2_4(D, S) \ -+do { \ -+ D##_f0 = S##_f[0]; \ -+ D##_f1 = S##_f[1]; \ -+} while (0) -+ -+/* Assembly/disassembly for converting to/from integral types. -+ * No shifting or overflow handled here. -+ */ -+/* Put the FP value X into r, which is an integer of size rsize. */ -+#define _FP_FRAC_ASSEMBLE_4(r, X, rsize) \ -+ do { \ -+ if (rsize <= _FP_W_TYPE_SIZE) \ -+ r = X##_f[0]; \ -+ else if (rsize <= 2*_FP_W_TYPE_SIZE) \ -+ { \ -+ r = X##_f[1]; \ -+ r <<= _FP_W_TYPE_SIZE; \ -+ r += X##_f[0]; \ -+ } \ -+ else \ -+ { \ -+ /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \ -+ /* and int == 4words as a single case. */ \ -+ r = X##_f[3]; \ -+ r <<= _FP_W_TYPE_SIZE; \ -+ r += X##_f[2]; \ -+ r <<= _FP_W_TYPE_SIZE; \ -+ r += X##_f[1]; \ -+ r <<= _FP_W_TYPE_SIZE; \ -+ r += X##_f[0]; \ -+ } \ -+ } while (0) -+ -+/* "No disassemble Number Five!" */ -+/* move an integer of size rsize into X's fractional part. We rely on -+ * the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid -+ * having to mask the values we store into it. -+ */ -+#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize) \ -+ do { \ -+ X##_f[0] = r; \ -+ X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ -+ X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \ -+ X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \ -+ } while (0); -+ -+#define _FP_FRAC_COPY_4_1(D, S) \ -+do { \ -+ D##_f[0] = S##_f; \ -+ D##_f[1] = D##_f[2] = D##_f[3] = 0; \ -+} while (0) -+ -+#define _FP_FRAC_COPY_4_2(D, S) \ -+do { \ -+ D##_f[0] = S##_f0; \ -+ D##_f[1] = S##_f1; \ -+ D##_f[2] = D##_f[3] = 0; \ -+} while (0) -+ -+#define _FP_FRAC_COPY_4_4(D,S) _FP_FRAC_COPY_4(D,S) -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-8.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-8.h ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-8.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-8.h 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,111 @@ -+/* Software floating-point emulation. -+ Basic eight-word fraction declaration and manipulation. -+ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com), -+ Jakub Jelinek (jj@ultra.linux.cz) and -+ Peter Maydell (pmaydell@chiark.greenend.org.uk). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ In addition to the permissions in the GNU Lesser General Public -+ License, the Free Software Foundation gives you unlimited -+ permission to link the compiled version of this file into -+ combinations with other programs, and to distribute those -+ combinations without any restriction coming from the use of this -+ file. (The Lesser General Public License restrictions do apply in -+ other respects; for example, they cover modification of the file, -+ and distribution when not linked into a combine executable.) -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -+ MA 02110-1301, USA. */ -+ -+/* We need just a few things from here for op-4, if we ever need some -+ other macros, they can be added. */ -+#define _FP_FRAC_DECL_8(X) _FP_W_TYPE X##_f[8] -+#define _FP_FRAC_HIGH_8(X) (X##_f[7]) -+#define _FP_FRAC_LOW_8(X) (X##_f[0]) -+#define _FP_FRAC_WORD_8(X,w) (X##_f[w]) -+ -+#define _FP_FRAC_SLL_8(X,N) \ -+ do { \ -+ _FP_I_TYPE _up, _down, _skip, _i; \ -+ _skip = (N) / _FP_W_TYPE_SIZE; \ -+ _up = (N) % _FP_W_TYPE_SIZE; \ -+ _down = _FP_W_TYPE_SIZE - _up; \ -+ if (!_up) \ -+ for (_i = 7; _i >= _skip; --_i) \ -+ X##_f[_i] = X##_f[_i-_skip]; \ -+ else \ -+ { \ -+ for (_i = 7; _i > _skip; --_i) \ -+ X##_f[_i] = X##_f[_i-_skip] << _up \ -+ | X##_f[_i-_skip-1] >> _down; \ -+ X##_f[_i--] = X##_f[0] << _up; \ -+ } \ -+ for (; _i >= 0; --_i) \ -+ X##_f[_i] = 0; \ -+ } while (0) -+ -+#define _FP_FRAC_SRL_8(X,N) \ -+ do { \ -+ _FP_I_TYPE _up, _down, _skip, _i; \ -+ _skip = (N) / _FP_W_TYPE_SIZE; \ -+ _down = (N) % _FP_W_TYPE_SIZE; \ -+ _up = _FP_W_TYPE_SIZE - _down; \ -+ if (!_down) \ -+ for (_i = 0; _i <= 7-_skip; ++_i) \ -+ X##_f[_i] = X##_f[_i+_skip]; \ -+ else \ -+ { \ -+ for (_i = 0; _i < 7-_skip; ++_i) \ -+ X##_f[_i] = X##_f[_i+_skip] >> _down \ -+ | X##_f[_i+_skip+1] << _up; \ -+ X##_f[_i++] = X##_f[7] >> _down; \ -+ } \ -+ for (; _i < 8; ++_i) \ -+ X##_f[_i] = 0; \ -+ } while (0) -+ -+ -+/* Right shift with sticky-lsb. -+ * What this actually means is that we do a standard right-shift, -+ * but that if any of the bits that fall off the right hand side -+ * were one then we always set the LSbit. -+ */ -+#define _FP_FRAC_SRS_8(X,N,size) \ -+ do { \ -+ _FP_I_TYPE _up, _down, _skip, _i; \ -+ _FP_W_TYPE _s; \ -+ _skip = (N) / _FP_W_TYPE_SIZE; \ -+ _down = (N) % _FP_W_TYPE_SIZE; \ -+ _up = _FP_W_TYPE_SIZE - _down; \ -+ for (_s = _i = 0; _i < _skip; ++_i) \ -+ _s |= X##_f[_i]; \ -+ if (!_down) \ -+ for (_i = 0; _i <= 7-_skip; ++_i) \ -+ X##_f[_i] = X##_f[_i+_skip]; \ -+ else \ -+ { \ -+ _s |= X##_f[_i] << _up; \ -+ for (_i = 0; _i < 7-_skip; ++_i) \ -+ X##_f[_i] = X##_f[_i+_skip] >> _down \ -+ | X##_f[_i+_skip+1] << _up; \ -+ X##_f[_i++] = X##_f[7] >> _down; \ -+ } \ -+ for (; _i < 8; ++_i) \ -+ X##_f[_i] = 0; \ -+ /* don't fix the LSB until the very end when we're sure f[0] is stable */ \ -+ X##_f[0] |= (_s != 0); \ -+ } while (0) -+ -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-common.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-common.h ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-common.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-common.h 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,1359 @@ -+/* Software floating-point emulation. Common operations. -+ Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com), -+ Jakub Jelinek (jj@ultra.linux.cz), -+ David S. Miller (davem@redhat.com) and -+ Peter Maydell (pmaydell@chiark.greenend.org.uk). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ In addition to the permissions in the GNU Lesser General Public -+ License, the Free Software Foundation gives you unlimited -+ permission to link the compiled version of this file into -+ combinations with other programs, and to distribute those -+ combinations without any restriction coming from the use of this -+ file. (The Lesser General Public License restrictions do apply in -+ other respects; for example, they cover modification of the file, -+ and distribution when not linked into a combine executable.) -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -+ MA 02110-1301, USA. */ -+ -+#define _FP_DECL(wc, X) \ -+ _FP_I_TYPE X##_c __attribute__((unused)), X##_s, X##_e; \ -+ _FP_FRAC_DECL_##wc(X) -+ -+/* -+ * Finish truely unpacking a native fp value by classifying the kind -+ * of fp value and normalizing both the exponent and the fraction. -+ */ -+ -+#define _FP_UNPACK_CANONICAL(fs, wc, X) \ -+do { \ -+ switch (X##_e) \ -+ { \ -+ default: \ -+ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ -+ _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \ -+ X##_e -= _FP_EXPBIAS_##fs; \ -+ X##_c = FP_CLS_NORMAL; \ -+ break; \ -+ \ -+ case 0: \ -+ if (_FP_FRAC_ZEROP_##wc(X)) \ -+ X##_c = FP_CLS_ZERO; \ -+ else \ -+ { \ -+ /* a denormalized number */ \ -+ _FP_I_TYPE _shift; \ -+ _FP_FRAC_CLZ_##wc(_shift, X); \ -+ _shift -= _FP_FRACXBITS_##fs; \ -+ _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \ -+ X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \ -+ X##_c = FP_CLS_NORMAL; \ -+ FP_SET_EXCEPTION(FP_EX_DENORM); \ -+ } \ -+ break; \ -+ \ -+ case _FP_EXPMAX_##fs: \ -+ if (_FP_FRAC_ZEROP_##wc(X)) \ -+ X##_c = FP_CLS_INF; \ -+ else \ -+ { \ -+ X##_c = FP_CLS_NAN; \ -+ /* Check for signaling NaN */ \ -+ if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \ -+ FP_SET_EXCEPTION(FP_EX_INVALID); \ -+ } \ -+ break; \ -+ } \ -+} while (0) -+ -+/* Finish unpacking an fp value in semi-raw mode: the mantissa is -+ shifted by _FP_WORKBITS but the implicit MSB is not inserted and -+ other classification is not done. */ -+#define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc(X, _FP_WORKBITS) -+ -+/* A semi-raw value has overflowed to infinity. Adjust the mantissa -+ and exponent appropriately. */ -+#define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \ -+do { \ -+ if (FP_ROUNDMODE == FP_RND_NEAREST \ -+ || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \ -+ || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \ -+ { \ -+ X##_e = _FP_EXPMAX_##fs; \ -+ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ -+ } \ -+ else \ -+ { \ -+ X##_e = _FP_EXPMAX_##fs - 1; \ -+ _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ -+ } \ -+ FP_SET_EXCEPTION(FP_EX_INEXACT); \ -+ FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ -+} while (0) -+ -+/* Check for a semi-raw value being a signaling NaN and raise the -+ invalid exception if so. */ -+#define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \ -+do { \ -+ if (X##_e == _FP_EXPMAX_##fs \ -+ && !_FP_FRAC_ZEROP_##wc(X) \ -+ && !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs)) \ -+ FP_SET_EXCEPTION(FP_EX_INVALID); \ -+} while (0) -+ -+/* Choose a NaN result from an operation on two semi-raw NaN -+ values. */ -+#define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \ -+do { \ -+ /* _FP_CHOOSENAN expects raw values, so shift as required. */ \ -+ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ -+ _FP_FRAC_SRL_##wc(Y, _FP_WORKBITS); \ -+ _FP_CHOOSENAN(fs, wc, R, X, Y, OP); \ -+ _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ -+} while (0) -+ -+/* Test whether a biased exponent is normal (not zero or maximum). */ -+#define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1) -+ -+/* Prepare to pack an fp value in semi-raw mode: the mantissa is -+ rounded and shifted right, with the rounding possibly increasing -+ the exponent (including changing a finite value to infinity). */ -+#define _FP_PACK_SEMIRAW(fs, wc, X) \ -+do { \ -+ _FP_ROUND(wc, X); \ -+ if (_FP_FRAC_HIGH_##fs(X) \ -+ & (_FP_OVERFLOW_##fs >> 1)) \ -+ { \ -+ _FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1); \ -+ X##_e++; \ -+ if (X##_e == _FP_EXPMAX_##fs) \ -+ _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ -+ } \ -+ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ -+ if (!_FP_EXP_NORMAL(fs, wc, X) && !_FP_FRAC_ZEROP_##wc(X)) \ -+ { \ -+ if (X##_e == 0) \ -+ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ -+ else \ -+ { \ -+ if (!_FP_KEEPNANFRACP) \ -+ { \ -+ _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ -+ X##_s = _FP_NANSIGN_##fs; \ -+ } \ -+ else \ -+ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \ -+ } \ -+ } \ -+} while (0) -+ -+/* -+ * Before packing the bits back into the native fp result, take care -+ * of such mundane things as rounding and overflow. Also, for some -+ * kinds of fp values, the original parts may not have been fully -+ * extracted -- but that is ok, we can regenerate them now. -+ */ -+ -+#define _FP_PACK_CANONICAL(fs, wc, X) \ -+do { \ -+ switch (X##_c) \ -+ { \ -+ case FP_CLS_NORMAL: \ -+ X##_e += _FP_EXPBIAS_##fs; \ -+ if (X##_e > 0) \ -+ { \ -+ _FP_ROUND(wc, X); \ -+ if (_FP_FRAC_OVERP_##wc(fs, X)) \ -+ { \ -+ _FP_FRAC_CLEAR_OVERP_##wc(fs, X); \ -+ X##_e++; \ -+ } \ -+ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ -+ if (X##_e >= _FP_EXPMAX_##fs) \ -+ { \ -+ /* overflow */ \ -+ switch (FP_ROUNDMODE) \ -+ { \ -+ case FP_RND_NEAREST: \ -+ X##_c = FP_CLS_INF; \ -+ break; \ -+ case FP_RND_PINF: \ -+ if (!X##_s) X##_c = FP_CLS_INF; \ -+ break; \ -+ case FP_RND_MINF: \ -+ if (X##_s) X##_c = FP_CLS_INF; \ -+ break; \ -+ } \ -+ if (X##_c == FP_CLS_INF) \ -+ { \ -+ /* Overflow to infinity */ \ -+ X##_e = _FP_EXPMAX_##fs; \ -+ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ -+ } \ -+ else \ -+ { \ -+ /* Overflow to maximum normal */ \ -+ X##_e = _FP_EXPMAX_##fs - 1; \ -+ _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ -+ } \ -+ FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ -+ FP_SET_EXCEPTION(FP_EX_INEXACT); \ -+ } \ -+ } \ -+ else \ -+ { \ -+ /* we've got a denormalized number */ \ -+ X##_e = -X##_e + 1; \ -+ if (X##_e <= _FP_WFRACBITS_##fs) \ -+ { \ -+ _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \ -+ _FP_ROUND(wc, X); \ -+ if (_FP_FRAC_HIGH_##fs(X) \ -+ & (_FP_OVERFLOW_##fs >> 1)) \ -+ { \ -+ X##_e = 1; \ -+ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ -+ } \ -+ else \ -+ { \ -+ X##_e = 0; \ -+ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ -+ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ -+ } \ -+ } \ -+ else \ -+ { \ -+ /* underflow to zero */ \ -+ X##_e = 0; \ -+ if (!_FP_FRAC_ZEROP_##wc(X)) \ -+ { \ -+ _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ -+ _FP_ROUND(wc, X); \ -+ _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \ -+ } \ -+ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ -+ } \ -+ } \ -+ break; \ -+ \ -+ case FP_CLS_ZERO: \ -+ X##_e = 0; \ -+ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ -+ break; \ -+ \ -+ case FP_CLS_INF: \ -+ X##_e = _FP_EXPMAX_##fs; \ -+ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ -+ break; \ -+ \ -+ case FP_CLS_NAN: \ -+ X##_e = _FP_EXPMAX_##fs; \ -+ if (!_FP_KEEPNANFRACP) \ -+ { \ -+ _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ -+ X##_s = _FP_NANSIGN_##fs; \ -+ } \ -+ else \ -+ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \ -+ break; \ -+ } \ -+} while (0) -+ -+/* This one accepts raw argument and not cooked, returns -+ * 1 if X is a signaling NaN. -+ */ -+#define _FP_ISSIGNAN(fs, wc, X) \ -+({ \ -+ int __ret = 0; \ -+ if (X##_e == _FP_EXPMAX_##fs) \ -+ { \ -+ if (!_FP_FRAC_ZEROP_##wc(X) \ -+ && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \ -+ __ret = 1; \ -+ } \ -+ __ret; \ -+}) -+ -+ -+ -+ -+ -+/* Addition on semi-raw values. */ -+#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \ -+do { \ -+ if (X##_s == Y##_s) \ -+ { \ -+ /* Addition. */ \ -+ R##_s = X##_s; \ -+ int ediff = X##_e - Y##_e; \ -+ if (ediff > 0) \ -+ { \ -+ R##_e = X##_e; \ -+ if (Y##_e == 0) \ -+ { \ -+ /* Y is zero or denormalized. */ \ -+ if (_FP_FRAC_ZEROP_##wc(Y)) \ -+ { \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ -+ _FP_FRAC_COPY_##wc(R, X); \ -+ goto add_done; \ -+ } \ -+ else \ -+ { \ -+ FP_SET_EXCEPTION(FP_EX_DENORM); \ -+ ediff--; \ -+ if (ediff == 0) \ -+ { \ -+ _FP_FRAC_ADD_##wc(R, X, Y); \ -+ goto add3; \ -+ } \ -+ if (X##_e == _FP_EXPMAX_##fs) \ -+ { \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ -+ _FP_FRAC_COPY_##wc(R, X); \ -+ goto add_done; \ -+ } \ -+ goto add1; \ -+ } \ -+ } \ -+ else if (X##_e == _FP_EXPMAX_##fs) \ -+ { \ -+ /* X is NaN or Inf, Y is normal. */ \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ -+ _FP_FRAC_COPY_##wc(R, X); \ -+ goto add_done; \ -+ } \ -+ \ -+ /* Insert implicit MSB of Y. */ \ -+ _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ -+ \ -+ add1: \ -+ /* Shift the mantissa of Y to the right EDIFF steps; \ -+ remember to account later for the implicit MSB of X. */ \ -+ if (ediff <= _FP_WFRACBITS_##fs) \ -+ _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ -+ else if (!_FP_FRAC_ZEROP_##wc(Y)) \ -+ _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ -+ _FP_FRAC_ADD_##wc(R, X, Y); \ -+ } \ -+ else if (ediff < 0) \ -+ { \ -+ ediff = -ediff; \ -+ R##_e = Y##_e; \ -+ if (X##_e == 0) \ -+ { \ -+ /* X is zero or denormalized. */ \ -+ if (_FP_FRAC_ZEROP_##wc(X)) \ -+ { \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ -+ _FP_FRAC_COPY_##wc(R, Y); \ -+ goto add_done; \ -+ } \ -+ else \ -+ { \ -+ FP_SET_EXCEPTION(FP_EX_DENORM); \ -+ ediff--; \ -+ if (ediff == 0) \ -+ { \ -+ _FP_FRAC_ADD_##wc(R, Y, X); \ -+ goto add3; \ -+ } \ -+ if (Y##_e == _FP_EXPMAX_##fs) \ -+ { \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ -+ _FP_FRAC_COPY_##wc(R, Y); \ -+ goto add_done; \ -+ } \ -+ goto add2; \ -+ } \ -+ } \ -+ else if (Y##_e == _FP_EXPMAX_##fs) \ -+ { \ -+ /* Y is NaN or Inf, X is normal. */ \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ -+ _FP_FRAC_COPY_##wc(R, Y); \ -+ goto add_done; \ -+ } \ -+ \ -+ /* Insert implicit MSB of X. */ \ -+ _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ -+ \ -+ add2: \ -+ /* Shift the mantissa of X to the right EDIFF steps; \ -+ remember to account later for the implicit MSB of Y. */ \ -+ if (ediff <= _FP_WFRACBITS_##fs) \ -+ _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ -+ else if (!_FP_FRAC_ZEROP_##wc(X)) \ -+ _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ -+ _FP_FRAC_ADD_##wc(R, Y, X); \ -+ } \ -+ else \ -+ { \ -+ /* ediff == 0. */ \ -+ if (!_FP_EXP_NORMAL(fs, wc, X)) \ -+ { \ -+ if (X##_e == 0) \ -+ { \ -+ /* X and Y are zero or denormalized. */ \ -+ R##_e = 0; \ -+ if (_FP_FRAC_ZEROP_##wc(X)) \ -+ { \ -+ if (!_FP_FRAC_ZEROP_##wc(Y)) \ -+ FP_SET_EXCEPTION(FP_EX_DENORM); \ -+ _FP_FRAC_COPY_##wc(R, Y); \ -+ goto add_done; \ -+ } \ -+ else if (_FP_FRAC_ZEROP_##wc(Y)) \ -+ { \ -+ FP_SET_EXCEPTION(FP_EX_DENORM); \ -+ _FP_FRAC_COPY_##wc(R, X); \ -+ goto add_done; \ -+ } \ -+ else \ -+ { \ -+ FP_SET_EXCEPTION(FP_EX_DENORM); \ -+ _FP_FRAC_ADD_##wc(R, X, Y); \ -+ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ -+ { \ -+ /* Normalized result. */ \ -+ _FP_FRAC_HIGH_##fs(R) \ -+ &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ -+ R##_e = 1; \ -+ } \ -+ goto add_done; \ -+ } \ -+ } \ -+ else \ -+ { \ -+ /* X and Y are NaN or Inf. */ \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ -+ R##_e = _FP_EXPMAX_##fs; \ -+ if (_FP_FRAC_ZEROP_##wc(X)) \ -+ _FP_FRAC_COPY_##wc(R, Y); \ -+ else if (_FP_FRAC_ZEROP_##wc(Y)) \ -+ _FP_FRAC_COPY_##wc(R, X); \ -+ else \ -+ _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ -+ goto add_done; \ -+ } \ -+ } \ -+ /* The exponents of X and Y, both normal, are equal. The \ -+ implicit MSBs will always add to increase the \ -+ exponent. */ \ -+ _FP_FRAC_ADD_##wc(R, X, Y); \ -+ R##_e = X##_e + 1; \ -+ _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ -+ if (R##_e == _FP_EXPMAX_##fs) \ -+ /* Overflow to infinity (depending on rounding mode). */ \ -+ _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ -+ goto add_done; \ -+ } \ -+ add3: \ -+ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ -+ { \ -+ /* Overflow. */ \ -+ _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ -+ R##_e++; \ -+ _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ -+ if (R##_e == _FP_EXPMAX_##fs) \ -+ /* Overflow to infinity (depending on rounding mode). */ \ -+ _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ -+ } \ -+ add_done: ; \ -+ } \ -+ else \ -+ { \ -+ /* Subtraction. */ \ -+ int ediff = X##_e - Y##_e; \ -+ if (ediff > 0) \ -+ { \ -+ R##_e = X##_e; \ -+ R##_s = X##_s; \ -+ if (Y##_e == 0) \ -+ { \ -+ /* Y is zero or denormalized. */ \ -+ if (_FP_FRAC_ZEROP_##wc(Y)) \ -+ { \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ -+ _FP_FRAC_COPY_##wc(R, X); \ -+ goto sub_done; \ -+ } \ -+ else \ -+ { \ -+ FP_SET_EXCEPTION(FP_EX_DENORM); \ -+ ediff--; \ -+ if (ediff == 0) \ -+ { \ -+ _FP_FRAC_SUB_##wc(R, X, Y); \ -+ goto sub3; \ -+ } \ -+ if (X##_e == _FP_EXPMAX_##fs) \ -+ { \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ -+ _FP_FRAC_COPY_##wc(R, X); \ -+ goto sub_done; \ -+ } \ -+ goto sub1; \ -+ } \ -+ } \ -+ else if (X##_e == _FP_EXPMAX_##fs) \ -+ { \ -+ /* X is NaN or Inf, Y is normal. */ \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ -+ _FP_FRAC_COPY_##wc(R, X); \ -+ goto sub_done; \ -+ } \ -+ \ -+ /* Insert implicit MSB of Y. */ \ -+ _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ -+ \ -+ sub1: \ -+ /* Shift the mantissa of Y to the right EDIFF steps; \ -+ remember to account later for the implicit MSB of X. */ \ -+ if (ediff <= _FP_WFRACBITS_##fs) \ -+ _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ -+ else if (!_FP_FRAC_ZEROP_##wc(Y)) \ -+ _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ -+ _FP_FRAC_SUB_##wc(R, X, Y); \ -+ } \ -+ else if (ediff < 0) \ -+ { \ -+ ediff = -ediff; \ -+ R##_e = Y##_e; \ -+ R##_s = Y##_s; \ -+ if (X##_e == 0) \ -+ { \ -+ /* X is zero or denormalized. */ \ -+ if (_FP_FRAC_ZEROP_##wc(X)) \ -+ { \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ -+ _FP_FRAC_COPY_##wc(R, Y); \ -+ goto sub_done; \ -+ } \ -+ else \ -+ { \ -+ FP_SET_EXCEPTION(FP_EX_DENORM); \ -+ ediff--; \ -+ if (ediff == 0) \ -+ { \ -+ _FP_FRAC_SUB_##wc(R, Y, X); \ -+ goto sub3; \ -+ } \ -+ if (Y##_e == _FP_EXPMAX_##fs) \ -+ { \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ -+ _FP_FRAC_COPY_##wc(R, Y); \ -+ goto sub_done; \ -+ } \ -+ goto sub2; \ -+ } \ -+ } \ -+ else if (Y##_e == _FP_EXPMAX_##fs) \ -+ { \ -+ /* Y is NaN or Inf, X is normal. */ \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ -+ _FP_FRAC_COPY_##wc(R, Y); \ -+ goto sub_done; \ -+ } \ -+ \ -+ /* Insert implicit MSB of X. */ \ -+ _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ -+ \ -+ sub2: \ -+ /* Shift the mantissa of X to the right EDIFF steps; \ -+ remember to account later for the implicit MSB of Y. */ \ -+ if (ediff <= _FP_WFRACBITS_##fs) \ -+ _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ -+ else if (!_FP_FRAC_ZEROP_##wc(X)) \ -+ _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ -+ _FP_FRAC_SUB_##wc(R, Y, X); \ -+ } \ -+ else \ -+ { \ -+ /* ediff == 0. */ \ -+ if (!_FP_EXP_NORMAL(fs, wc, X)) \ -+ { \ -+ if (X##_e == 0) \ -+ { \ -+ /* X and Y are zero or denormalized. */ \ -+ R##_e = 0; \ -+ if (_FP_FRAC_ZEROP_##wc(X)) \ -+ { \ -+ _FP_FRAC_COPY_##wc(R, Y); \ -+ if (_FP_FRAC_ZEROP_##wc(Y)) \ -+ R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ -+ else \ -+ { \ -+ FP_SET_EXCEPTION(FP_EX_DENORM); \ -+ R##_s = Y##_s; \ -+ } \ -+ goto sub_done; \ -+ } \ -+ else if (_FP_FRAC_ZEROP_##wc(Y)) \ -+ { \ -+ FP_SET_EXCEPTION(FP_EX_DENORM); \ -+ _FP_FRAC_COPY_##wc(R, X); \ -+ R##_s = X##_s; \ -+ goto sub_done; \ -+ } \ -+ else \ -+ { \ -+ FP_SET_EXCEPTION(FP_EX_DENORM); \ -+ _FP_FRAC_SUB_##wc(R, X, Y); \ -+ R##_s = X##_s; \ -+ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ -+ { \ -+ /* |X| < |Y|, negate result. */ \ -+ _FP_FRAC_SUB_##wc(R, Y, X); \ -+ R##_s = Y##_s; \ -+ } \ -+ else if (_FP_FRAC_ZEROP_##wc(R)) \ -+ R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ -+ goto sub_done; \ -+ } \ -+ } \ -+ else \ -+ { \ -+ /* X and Y are NaN or Inf, of opposite signs. */ \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ -+ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ -+ R##_e = _FP_EXPMAX_##fs; \ -+ if (_FP_FRAC_ZEROP_##wc(X)) \ -+ { \ -+ if (_FP_FRAC_ZEROP_##wc(Y)) \ -+ { \ -+ /* Inf - Inf. */ \ -+ R##_s = _FP_NANSIGN_##fs; \ -+ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ -+ _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ -+ FP_SET_EXCEPTION(FP_EX_INVALID); \ -+ } \ -+ else \ -+ { \ -+ /* Inf - NaN. */ \ -+ R##_s = Y##_s; \ -+ _FP_FRAC_COPY_##wc(R, Y); \ -+ } \ -+ } \ -+ else \ -+ { \ -+ if (_FP_FRAC_ZEROP_##wc(Y)) \ -+ { \ -+ /* NaN - Inf. */ \ -+ R##_s = X##_s; \ -+ _FP_FRAC_COPY_##wc(R, X); \ -+ } \ -+ else \ -+ { \ -+ /* NaN - NaN. */ \ -+ _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ -+ } \ -+ } \ -+ goto sub_done; \ -+ } \ -+ } \ -+ /* The exponents of X and Y, both normal, are equal. The \ -+ implicit MSBs cancel. */ \ -+ R##_e = X##_e; \ -+ _FP_FRAC_SUB_##wc(R, X, Y); \ -+ R##_s = X##_s; \ -+ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ -+ { \ -+ /* |X| < |Y|, negate result. */ \ -+ _FP_FRAC_SUB_##wc(R, Y, X); \ -+ R##_s = Y##_s; \ -+ } \ -+ else if (_FP_FRAC_ZEROP_##wc(R)) \ -+ { \ -+ R##_e = 0; \ -+ R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ -+ goto sub_done; \ -+ } \ -+ goto norm; \ -+ } \ -+ sub3: \ -+ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ -+ { \ -+ int diff; \ -+ /* Carry into most significant bit of larger one of X and Y, \ -+ canceling it; renormalize. */ \ -+ _FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1; \ -+ norm: \ -+ _FP_FRAC_CLZ_##wc(diff, R); \ -+ diff -= _FP_WFRACXBITS_##fs; \ -+ _FP_FRAC_SLL_##wc(R, diff); \ -+ if (R##_e <= diff) \ -+ { \ -+ /* R is denormalized. */ \ -+ diff = diff - R##_e + 1; \ -+ _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \ -+ R##_e = 0; \ -+ } \ -+ else \ -+ { \ -+ R##_e -= diff; \ -+ _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ -+ } \ -+ } \ -+ sub_done: ; \ -+ } \ -+} while (0) -+ -+#define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+') -+#define _FP_SUB(fs, wc, R, X, Y) \ -+ do { \ -+ if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \ -+ _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-'); \ -+ } while (0) -+ -+ -+/* -+ * Main negation routine. FIXME -- when we care about setting exception -+ * bits reliably, this will not do. We should examine all of the fp classes. -+ */ -+ -+#define _FP_NEG(fs, wc, R, X) \ -+ do { \ -+ _FP_FRAC_COPY_##wc(R, X); \ -+ R##_c = X##_c; \ -+ R##_e = X##_e; \ -+ R##_s = 1 ^ X##_s; \ -+ } while (0) -+ -+ -+/* -+ * Main multiplication routine. The input values should be cooked. -+ */ -+ -+#define _FP_MUL(fs, wc, R, X, Y) \ -+do { \ -+ R##_s = X##_s ^ Y##_s; \ -+ switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ -+ { \ -+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ -+ R##_c = FP_CLS_NORMAL; \ -+ R##_e = X##_e + Y##_e + 1; \ -+ \ -+ _FP_MUL_MEAT_##fs(R,X,Y); \ -+ \ -+ if (_FP_FRAC_OVERP_##wc(fs, R)) \ -+ _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ -+ else \ -+ R##_e--; \ -+ break; \ -+ \ -+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ -+ _FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \ -+ break; \ -+ \ -+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ -+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ -+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ -+ R##_s = X##_s; \ -+ \ -+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ -+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ -+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ -+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ -+ _FP_FRAC_COPY_##wc(R, X); \ -+ R##_c = X##_c; \ -+ break; \ -+ \ -+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ -+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ -+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ -+ R##_s = Y##_s; \ -+ \ -+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ -+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ -+ _FP_FRAC_COPY_##wc(R, Y); \ -+ R##_c = Y##_c; \ -+ break; \ -+ \ -+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ -+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ -+ R##_s = _FP_NANSIGN_##fs; \ -+ R##_c = FP_CLS_NAN; \ -+ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ -+ FP_SET_EXCEPTION(FP_EX_INVALID); \ -+ break; \ -+ \ -+ default: \ -+ abort(); \ -+ } \ -+} while (0) -+ -+ -+/* -+ * Main division routine. The input values should be cooked. -+ */ -+ -+#define _FP_DIV(fs, wc, R, X, Y) \ -+do { \ -+ R##_s = X##_s ^ Y##_s; \ -+ switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ -+ { \ -+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ -+ R##_c = FP_CLS_NORMAL; \ -+ R##_e = X##_e - Y##_e; \ -+ \ -+ _FP_DIV_MEAT_##fs(R,X,Y); \ -+ break; \ -+ \ -+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ -+ _FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \ -+ break; \ -+ \ -+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ -+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ -+ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ -+ R##_s = X##_s; \ -+ _FP_FRAC_COPY_##wc(R, X); \ -+ R##_c = X##_c; \ -+ break; \ -+ \ -+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ -+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ -+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ -+ R##_s = Y##_s; \ -+ _FP_FRAC_COPY_##wc(R, Y); \ -+ R##_c = Y##_c; \ -+ break; \ -+ \ -+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ -+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ -+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ -+ R##_c = FP_CLS_ZERO; \ -+ break; \ -+ \ -+ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ -+ FP_SET_EXCEPTION(FP_EX_DIVZERO); \ -+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ -+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ -+ R##_c = FP_CLS_INF; \ -+ break; \ -+ \ -+ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ -+ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ -+ R##_s = _FP_NANSIGN_##fs; \ -+ R##_c = FP_CLS_NAN; \ -+ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ -+ FP_SET_EXCEPTION(FP_EX_INVALID); \ -+ break; \ -+ \ -+ default: \ -+ abort(); \ -+ } \ -+} while (0) -+ -+ -+/* -+ * Main differential comparison routine. The inputs should be raw not -+ * cooked. The return is -1,0,1 for normal values, 2 otherwise. -+ */ -+ -+#define _FP_CMP(fs, wc, ret, X, Y, un) \ -+ do { \ -+ /* NANs are unordered */ \ -+ if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ -+ || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ -+ { \ -+ ret = un; \ -+ } \ -+ else \ -+ { \ -+ int __is_zero_x; \ -+ int __is_zero_y; \ -+ \ -+ __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \ -+ __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \ -+ \ -+ if (__is_zero_x && __is_zero_y) \ -+ ret = 0; \ -+ else if (__is_zero_x) \ -+ ret = Y##_s ? 1 : -1; \ -+ else if (__is_zero_y) \ -+ ret = X##_s ? -1 : 1; \ -+ else if (X##_s != Y##_s) \ -+ ret = X##_s ? -1 : 1; \ -+ else if (X##_e > Y##_e) \ -+ ret = X##_s ? -1 : 1; \ -+ else if (X##_e < Y##_e) \ -+ ret = X##_s ? 1 : -1; \ -+ else if (_FP_FRAC_GT_##wc(X, Y)) \ -+ ret = X##_s ? -1 : 1; \ -+ else if (_FP_FRAC_GT_##wc(Y, X)) \ -+ ret = X##_s ? 1 : -1; \ -+ else \ -+ ret = 0; \ -+ } \ -+ } while (0) -+ -+ -+/* Simplification for strict equality. */ -+ -+#define _FP_CMP_EQ(fs, wc, ret, X, Y) \ -+ do { \ -+ /* NANs are unordered */ \ -+ if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ -+ || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ -+ { \ -+ ret = 1; \ -+ } \ -+ else \ -+ { \ -+ ret = !(X##_e == Y##_e \ -+ && _FP_FRAC_EQ_##wc(X, Y) \ -+ && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \ -+ } \ -+ } while (0) -+ -+/* Version to test unordered. */ -+ -+#define _FP_CMP_UNORD(fs, wc, ret, X, Y) \ -+ do { \ -+ ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ -+ || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))); \ -+ } while (0) -+ -+/* -+ * Main square root routine. The input value should be cooked. -+ */ -+ -+#define _FP_SQRT(fs, wc, R, X) \ -+do { \ -+ _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \ -+ _FP_W_TYPE q; \ -+ switch (X##_c) \ -+ { \ -+ case FP_CLS_NAN: \ -+ _FP_FRAC_COPY_##wc(R, X); \ -+ R##_s = X##_s; \ -+ R##_c = FP_CLS_NAN; \ -+ break; \ -+ case FP_CLS_INF: \ -+ if (X##_s) \ -+ { \ -+ R##_s = _FP_NANSIGN_##fs; \ -+ R##_c = FP_CLS_NAN; /* NAN */ \ -+ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ -+ FP_SET_EXCEPTION(FP_EX_INVALID); \ -+ } \ -+ else \ -+ { \ -+ R##_s = 0; \ -+ R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \ -+ } \ -+ break; \ -+ case FP_CLS_ZERO: \ -+ R##_s = X##_s; \ -+ R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \ -+ break; \ -+ case FP_CLS_NORMAL: \ -+ R##_s = 0; \ -+ if (X##_s) \ -+ { \ -+ R##_c = FP_CLS_NAN; /* sNAN */ \ -+ R##_s = _FP_NANSIGN_##fs; \ -+ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ -+ FP_SET_EXCEPTION(FP_EX_INVALID); \ -+ break; \ -+ } \ -+ R##_c = FP_CLS_NORMAL; \ -+ if (X##_e & 1) \ -+ _FP_FRAC_SLL_##wc(X, 1); \ -+ R##_e = X##_e >> 1; \ -+ _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \ -+ _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \ -+ q = _FP_OVERFLOW_##fs >> 1; \ -+ _FP_SQRT_MEAT_##wc(R, S, T, X, q); \ -+ } \ -+ } while (0) -+ -+/* -+ * Convert from FP to integer. Input is raw. -+ */ -+ -+/* RSIGNED can have following values: -+ * 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus -+ * the result is either 0 or (2^rsize)-1 depending on the sign in such -+ * case. -+ * 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, -+ * NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 -+ * depending on the sign in such case. -+ * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is -+ * set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 -+ * depending on the sign in such case. -+ */ -+#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \ -+do { \ -+ if (X##_e < _FP_EXPBIAS_##fs) \ -+ { \ -+ r = 0; \ -+ if (X##_e == 0) \ -+ { \ -+ if (!_FP_FRAC_ZEROP_##wc(X)) \ -+ { \ -+ FP_SET_EXCEPTION(FP_EX_INEXACT); \ -+ FP_SET_EXCEPTION(FP_EX_DENORM); \ -+ } \ -+ } \ -+ else \ -+ FP_SET_EXCEPTION(FP_EX_INEXACT); \ -+ } \ -+ else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \ -+ || (!rsigned && X##_s)) \ -+ { \ -+ /* Overflow or converting to the most negative integer. */ \ -+ if (rsigned) \ -+ { \ -+ r = 1; \ -+ r <<= rsize - 1; \ -+ r -= 1 - X##_s; \ -+ } else { \ -+ r = 0; \ -+ if (X##_s) \ -+ r = ~r; \ -+ } \ -+ \ -+ if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \ -+ { \ -+ /* Possibly converting to most negative integer; check the \ -+ mantissa. */ \ -+ int inexact = 0; \ -+ (void)((_FP_FRACBITS_##fs > rsize) \ -+ ? ({ _FP_FRAC_SRST_##wc(X, inexact, \ -+ _FP_FRACBITS_##fs - rsize, \ -+ _FP_FRACBITS_##fs); 0; }) \ -+ : 0); \ -+ if (!_FP_FRAC_ZEROP_##wc(X)) \ -+ FP_SET_EXCEPTION(FP_EX_INVALID); \ -+ else if (inexact) \ -+ FP_SET_EXCEPTION(FP_EX_INEXACT); \ -+ } \ -+ else \ -+ FP_SET_EXCEPTION(FP_EX_INVALID); \ -+ } \ -+ else \ -+ { \ -+ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ -+ if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \ -+ { \ -+ _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ -+ r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \ -+ } \ -+ else \ -+ { \ -+ int inexact; \ -+ _FP_FRAC_SRST_##wc(X, inexact, \ -+ (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \ -+ - X##_e), \ -+ _FP_FRACBITS_##fs); \ -+ if (inexact) \ -+ FP_SET_EXCEPTION(FP_EX_INEXACT); \ -+ _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ -+ } \ -+ if (rsigned && X##_s) \ -+ r = -r; \ -+ } \ -+} while (0) -+ -+/* Convert integer to fp. Output is raw. RTYPE is unsigned even if -+ input is signed. */ -+#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \ -+ do { \ -+ if (r) \ -+ { \ -+ rtype ur_; \ -+ \ -+ if ((X##_s = (r < 0))) \ -+ r = -(rtype)r; \ -+ \ -+ ur_ = (rtype) r; \ -+ (void)((rsize <= _FP_W_TYPE_SIZE) \ -+ ? ({ \ -+ int lz_; \ -+ __FP_CLZ(lz_, (_FP_W_TYPE)ur_); \ -+ X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \ -+ }) \ -+ : ((rsize <= 2 * _FP_W_TYPE_SIZE) \ -+ ? ({ \ -+ int lz_; \ -+ __FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \ -+ (_FP_W_TYPE)ur_); \ -+ X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \ -+ - lz_); \ -+ }) \ -+ : (abort(), 0))); \ -+ \ -+ if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \ -+ && X##_e >= _FP_EXPMAX_##fs) \ -+ { \ -+ /* Exponent too big; overflow to infinity. (May also \ -+ happen after rounding below.) */ \ -+ _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ -+ goto pack_semiraw; \ -+ } \ -+ \ -+ if (rsize <= _FP_FRACBITS_##fs \ -+ || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \ -+ { \ -+ /* Exactly representable; shift left. */ \ -+ _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ -+ _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ -+ + _FP_FRACBITS_##fs - 1 - X##_e)); \ -+ } \ -+ else \ -+ { \ -+ /* More bits in integer than in floating type; need to \ -+ round. */ \ -+ if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \ -+ ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \ -+ - _FP_WFRACBITS_##fs + 1)) \ -+ | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \ -+ - _FP_WFRACBITS_##fs + 1))) \ -+ != 0)); \ -+ _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ -+ if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \ -+ _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ -+ + _FP_WFRACBITS_##fs - 1 - X##_e)); \ -+ _FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ -+ pack_semiraw: \ -+ _FP_PACK_SEMIRAW(fs, wc, X); \ -+ } \ -+ } \ -+ else \ -+ { \ -+ X##_s = 0; \ -+ X##_e = 0; \ -+ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ -+ } \ -+ } while (0) -+ -+ -+/* Extend from a narrower floating-point format to a wider one. Input -+ and output are raw. */ -+#define FP_EXTEND(dfs,sfs,dwc,swc,D,S) \ -+do { \ -+ if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \ -+ || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \ -+ < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \ -+ || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \ -+ && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \ -+ abort(); \ -+ D##_s = S##_s; \ -+ _FP_FRAC_COPY_##dwc##_##swc(D, S); \ -+ if (_FP_EXP_NORMAL(sfs, swc, S)) \ -+ { \ -+ D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ -+ _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \ -+ } \ -+ else \ -+ { \ -+ if (S##_e == 0) \ -+ { \ -+ if (_FP_FRAC_ZEROP_##swc(S)) \ -+ D##_e = 0; \ -+ else if (_FP_EXPBIAS_##dfs \ -+ < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \ -+ { \ -+ FP_SET_EXCEPTION(FP_EX_DENORM); \ -+ _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ -+ - _FP_FRACBITS_##sfs)); \ -+ D##_e = 0; \ -+ } \ -+ else \ -+ { \ -+ int _lz; \ -+ FP_SET_EXCEPTION(FP_EX_DENORM); \ -+ _FP_FRAC_CLZ_##swc(_lz, S); \ -+ _FP_FRAC_SLL_##dwc(D, \ -+ _lz + _FP_FRACBITS_##dfs \ -+ - _FP_FRACTBITS_##sfs); \ -+ D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \ -+ + _FP_FRACXBITS_##sfs - _lz); \ -+ } \ -+ } \ -+ else \ -+ { \ -+ D##_e = _FP_EXPMAX_##dfs; \ -+ if (!_FP_FRAC_ZEROP_##swc(S)) \ -+ { \ -+ if (!(_FP_FRAC_HIGH_RAW_##sfs(S) & _FP_QNANBIT_##sfs)) \ -+ FP_SET_EXCEPTION(FP_EX_INVALID); \ -+ _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ -+ - _FP_FRACBITS_##sfs)); \ -+ } \ -+ } \ -+ } \ -+} while (0) -+ -+/* Truncate from a wider floating-point format to a narrower one. -+ Input and output are semi-raw. */ -+#define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \ -+do { \ -+ if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \ -+ || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \ -+ && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \ -+ abort(); \ -+ D##_s = S##_s; \ -+ if (_FP_EXP_NORMAL(sfs, swc, S)) \ -+ { \ -+ D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ -+ if (D##_e >= _FP_EXPMAX_##dfs) \ -+ _FP_OVERFLOW_SEMIRAW(dfs, dwc, D); \ -+ else \ -+ { \ -+ if (D##_e <= 0) \ -+ { \ -+ if (D##_e < 1 - _FP_FRACBITS_##dfs) \ -+ { \ -+ _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \ -+ _FP_FRAC_LOW_##swc(S) |= 1; \ -+ } \ -+ else \ -+ { \ -+ _FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs; \ -+ _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ -+ - _FP_WFRACBITS_##dfs + 1 - D##_e), \ -+ _FP_WFRACBITS_##sfs); \ -+ } \ -+ D##_e = 0; \ -+ } \ -+ else \ -+ _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ -+ - _FP_WFRACBITS_##dfs), \ -+ _FP_WFRACBITS_##sfs); \ -+ _FP_FRAC_COPY_##dwc##_##swc(D, S); \ -+ } \ -+ } \ -+ else \ -+ { \ -+ if (S##_e == 0) \ -+ { \ -+ D##_e = 0; \ -+ if (_FP_FRAC_ZEROP_##swc(S)) \ -+ _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ -+ else \ -+ { \ -+ FP_SET_EXCEPTION(FP_EX_DENORM); \ -+ if (_FP_EXPBIAS_##sfs \ -+ < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \ -+ { \ -+ _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ -+ - _FP_WFRACBITS_##dfs), \ -+ _FP_WFRACBITS_##sfs); \ -+ _FP_FRAC_COPY_##dwc##_##swc(D, S); \ -+ } \ -+ else \ -+ { \ -+ _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ -+ _FP_FRAC_LOW_##dwc(D) |= 1; \ -+ } \ -+ } \ -+ } \ -+ else \ -+ { \ -+ D##_e = _FP_EXPMAX_##dfs; \ -+ if (_FP_FRAC_ZEROP_##swc(S)) \ -+ _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ -+ else \ -+ { \ -+ _FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S); \ -+ _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs \ -+ - _FP_WFRACBITS_##dfs)); \ -+ _FP_FRAC_COPY_##dwc##_##swc(D, S); \ -+ /* Semi-raw NaN must have all workbits cleared. */ \ -+ _FP_FRAC_LOW_##dwc(D) \ -+ &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \ -+ _FP_FRAC_HIGH_##dfs(D) |= _FP_QNANBIT_SH_##dfs; \ -+ } \ -+ } \ -+ } \ -+} while (0) -+ -+/* -+ * Helper primitives. -+ */ -+ -+/* Count leading zeros in a word. */ -+ -+#ifndef __FP_CLZ -+/* GCC 3.4 and later provide the builtins for us. */ -+#define __FP_CLZ(r, x) \ -+ do { \ -+ if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \ -+ r = __builtin_clz (x); \ -+ else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \ -+ r = __builtin_clzl (x); \ -+ else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \ -+ r = __builtin_clzll (x); \ -+ else \ -+ abort (); \ -+ } while (0) -+#endif /* ndef __FP_CLZ */ -+ -+#define _FP_DIV_HELP_imm(q, r, n, d) \ -+ do { \ -+ q = n / d, r = n % d; \ -+ } while (0) -+ -+ -+/* A restoring bit-by-bit division primitive. */ -+ -+#define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \ -+ do { \ -+ int count = _FP_WFRACBITS_##fs; \ -+ _FP_FRAC_DECL_##wc (u); \ -+ _FP_FRAC_DECL_##wc (v); \ -+ _FP_FRAC_COPY_##wc (u, X); \ -+ _FP_FRAC_COPY_##wc (v, Y); \ -+ _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ -+ /* Normalize U and V. */ \ -+ _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \ -+ _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \ -+ /* First round. Since the operands are normalized, either the \ -+ first or second bit will be set in the fraction. Produce a \ -+ normalized result by checking which and adjusting the loop \ -+ count and exponent accordingly. */ \ -+ if (_FP_FRAC_GE_1 (u, v)) \ -+ { \ -+ _FP_FRAC_SUB_##wc (u, u, v); \ -+ _FP_FRAC_LOW_##wc (R) |= 1; \ -+ count--; \ -+ } \ -+ else \ -+ R##_e--; \ -+ /* Subsequent rounds. */ \ -+ do { \ -+ int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \ -+ _FP_FRAC_SLL_##wc (u, 1); \ -+ _FP_FRAC_SLL_##wc (R, 1); \ -+ if (msb || _FP_FRAC_GE_1 (u, v)) \ -+ { \ -+ _FP_FRAC_SUB_##wc (u, u, v); \ -+ _FP_FRAC_LOW_##wc (R) |= 1; \ -+ } \ -+ } while (--count > 0); \ -+ /* If there's anything left in U, the result is inexact. */ \ -+ _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \ -+ } while (0) -+ -+#define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y) -+#define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y) -+#define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y) -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_add.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_add.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_add.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_add.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,39 @@ -+/* Software floating-point emulation. -+ Return a + b -+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+long double _Q_add(const long double a, const long double b) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); -+ long double c; -+ -+ FP_INIT_ROUNDMODE; -+ FP_UNPACK_SEMIRAW_Q(A, a); -+ FP_UNPACK_SEMIRAW_Q(B, b); -+ FP_ADD_Q(C, A, B); -+ FP_PACK_SEMIRAW_Q(c, C); -+ FP_HANDLE_EXCEPTIONS; -+ return c; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_cmp.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_cmp.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_cmp.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_cmp.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,41 @@ -+/* Software floating-point emulation. -+ Compare a and b, return float condition code. -+ Copyright (C) 1997,1999 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+int _Q_cmp(const long double a, const long double b) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); FP_DECL_Q(B); -+ int r; -+ -+ FP_UNPACK_RAW_Q(A, a); -+ FP_UNPACK_RAW_Q(B, b); -+ FP_CMP_Q(r, B, A, 3); -+ if (r == -1) r = 2; -+ if (r == 3 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))) -+ FP_SET_EXCEPTION(FP_EX_INVALID); -+ FP_HANDLE_EXCEPTIONS; -+ -+ return r; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_cmpe.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_cmpe.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_cmpe.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_cmpe.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,42 @@ -+/* Software floating-point emulation. -+ Compare a and b, return float condition code. -+ Signal exception (unless masked) if unordered. -+ Copyright (C) 1997,1999 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+int _Q_cmpe(const long double a, const long double b) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); FP_DECL_Q(B); -+ int r; -+ -+ FP_UNPACK_RAW_Q(A, a); -+ FP_UNPACK_RAW_Q(B, b); -+ FP_CMP_Q(r, B, A, 3); -+ if (r == -1) r = 2; -+ if (r == 3) -+ FP_SET_EXCEPTION(FP_EX_INVALID); -+ FP_HANDLE_EXCEPTIONS; -+ -+ return r; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_div.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_div.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_div.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_div.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,39 @@ -+/* Software floating-point emulation. -+ Return a / b -+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+long double _Q_div(const long double a, const long double b) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); -+ long double c; -+ -+ FP_INIT_ROUNDMODE; -+ FP_UNPACK_Q(A, a); -+ FP_UNPACK_Q(B, b); -+ FP_DIV_Q(C, A, B); -+ FP_PACK_Q(c, C); -+ FP_HANDLE_EXCEPTIONS; -+ return c; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_dtoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_dtoq.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_dtoq.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_dtoq.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,44 @@ -+/* Software floating-point emulation. -+ Return (long double)(a) -+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "double.h" -+#include "quad.h" -+ -+long double _Q_dtoq(const double a) -+{ -+ FP_DECL_EX; -+ FP_DECL_D(A); -+ FP_DECL_Q(C); -+ long double c; -+ -+ FP_INIT_ROUNDMODE; -+ FP_UNPACK_RAW_D(A, a); -+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q -+ FP_EXTEND(Q,D,4,2,C,A); -+#else -+ FP_EXTEND(Q,D,2,1,C,A); -+#endif -+ FP_PACK_RAW_Q(c, C); -+ FP_HANDLE_EXCEPTIONS; -+ return c; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_feq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_feq.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_feq.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_feq.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,40 @@ -+/* Software floating-point emulation. -+ Return 1 if a == b -+ Copyright (C) 1997,1999 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+int _Q_feq(const long double a, const long double b) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); FP_DECL_Q(B); -+ int r; -+ -+ FP_UNPACK_RAW_Q(A, a); -+ FP_UNPACK_RAW_Q(B, b); -+ FP_CMP_EQ_Q(r, A, B); -+ if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))) -+ FP_SET_EXCEPTION(FP_EX_INVALID); -+ FP_HANDLE_EXCEPTIONS; -+ -+ return !r; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fge.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fge.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fge.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fge.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,40 @@ -+/* Software floating-point emulation. -+ Return 1 if a >= b -+ Copyright (C) 1997,1999 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+int _Q_fge(const long double a, const long double b) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); FP_DECL_Q(B); -+ int r; -+ -+ FP_UNPACK_RAW_Q(A, a); -+ FP_UNPACK_RAW_Q(B, b); -+ FP_CMP_Q(r, B, A, 3); -+ if (r == 3) -+ FP_SET_EXCEPTION(FP_EX_INVALID); -+ FP_HANDLE_EXCEPTIONS; -+ -+ return (r <= 0); -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fgt.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fgt.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fgt.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fgt.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,40 @@ -+/* Software floating-point emulation. -+ Return 1 if a > b -+ Copyright (C) 1997,1999 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+int _Q_fgt(const long double a, const long double b) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); FP_DECL_Q(B); -+ int r; -+ -+ FP_UNPACK_RAW_Q(A, a); -+ FP_UNPACK_RAW_Q(B, b); -+ FP_CMP_Q(r, B, A, 3); -+ if (r == 3) -+ FP_SET_EXCEPTION(FP_EX_INVALID); -+ FP_HANDLE_EXCEPTIONS; -+ -+ return (r == -1); -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fle.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fle.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fle.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fle.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,40 @@ -+/* Software floating-point emulation. -+ Return 1 if a <= b -+ Copyright (C) 1997,1999 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+int _Q_fle(const long double a, const long double b) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); FP_DECL_Q(B); -+ int r; -+ -+ FP_UNPACK_RAW_Q(A, a); -+ FP_UNPACK_RAW_Q(B, b); -+ FP_CMP_Q(r, B, A, -2); -+ if (r == -2) -+ FP_SET_EXCEPTION(FP_EX_INVALID); -+ FP_HANDLE_EXCEPTIONS; -+ -+ return (r >= 0); -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_flt.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_flt.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_flt.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_flt.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,40 @@ -+/* Software floating-point emulation. -+ Return 1 if a < b -+ Copyright (C) 1997,1999 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+int _Q_flt(const long double a, const long double b) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); FP_DECL_Q(B); -+ int r; -+ -+ FP_UNPACK_RAW_Q(A, a); -+ FP_UNPACK_RAW_Q(B, b); -+ FP_CMP_Q(r, B, A, 3); -+ if (r == 3) -+ FP_SET_EXCEPTION(FP_EX_INVALID); -+ FP_HANDLE_EXCEPTIONS; -+ -+ return (r == 1); -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fne.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fne.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fne.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fne.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,40 @@ -+/* Software floating-point emulation. -+ Return 1 if a != b -+ Copyright (C) 1997,1999 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+int _Q_fne(const long double a, const long double b) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); FP_DECL_Q(B); -+ int r; -+ -+ FP_UNPACK_RAW_Q(A, a); -+ FP_UNPACK_RAW_Q(B, b); -+ FP_CMP_EQ_Q(r, A, B); -+ if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))) -+ FP_SET_EXCEPTION(FP_EX_INVALID); -+ FP_HANDLE_EXCEPTIONS; -+ -+ return r; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_itoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_itoq.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_itoq.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_itoq.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,38 @@ -+/* Software floating-point emulation. -+ Return (long double)(a) -+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+long double _Q_itoq(const int a) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(C); -+ int b = a; -+ long double c; -+ -+ FP_FROM_INT_Q(C, b, 32, unsigned int); -+ FP_PACK_RAW_Q(c, C); -+ FP_CLEAR_EXCEPTIONS; -+ FP_HANDLE_EXCEPTIONS; -+ return c; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_lltoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_lltoq.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_lltoq.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_lltoq.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,38 @@ -+/* Software floating-point emulation. -+ Return (long double)a -+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+long double _Q_lltoq(const long long a) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(C); -+ long double c; -+ long long b = a; -+ -+ FP_FROM_INT_Q(C, b, 64, unsigned long long); -+ FP_PACK_RAW_Q(c, C); -+ FP_CLEAR_EXCEPTIONS; -+ FP_HANDLE_EXCEPTIONS; -+ return c; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_mul.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_mul.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_mul.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_mul.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,39 @@ -+/* Software floating-point emulation. -+ Return a * b -+ Copyright (C) 1997,1999 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+long double _Q_mul(const long double a, const long double b) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); -+ long double c; -+ -+ FP_INIT_ROUNDMODE; -+ FP_UNPACK_Q(A, a); -+ FP_UNPACK_Q(B, b); -+ FP_MUL_Q(C, A, B); -+ FP_PACK_Q(c, C); -+ FP_HANDLE_EXCEPTIONS; -+ return c; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_neg.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_neg.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_neg.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_neg.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,47 @@ -+/* Software floating-point emulation. -+ Return !a -+ Copyright (C) 1997,1999 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+long double _Q_neg(const long double a) -+{ -+ FP_DECL_EX; -+ long double c = a; -+ -+#if (__BYTE_ORDER == __BIG_ENDIAN) -+ ((UWtype *)&c)[0] ^= (((UWtype)1) << (W_TYPE_SIZE - 1)); -+#elif (__BYTE_ORDER == __LITTLE_ENDIAN) && (W_TYPE_SIZE == 64) -+ ((UWtype *)&c)[1] ^= (((UWtype)1) << (W_TYPE_SIZE - 1)); -+#elif (__BYTE_ORDER == __LITTLE_ENDIAN) && (W_TYPE_SIZE == 32) -+ ((UWtype *)&c)[3] ^= (((UWtype)1) << (W_TYPE_SIZE - 1)); -+#else -+ FP_DECL_Q(A); FP_DECL_Q(C); -+ -+ FP_UNPACK_Q(A, a); -+ FP_NEG_Q(C, A); -+ FP_PACK_Q(c, C); -+#endif -+ FP_CLEAR_EXCEPTIONS; -+ FP_HANDLE_EXCEPTIONS; -+ return c; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtod.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtod.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtod.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtod.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,45 @@ -+/* Software floating-point emulation. -+ Return (double)a -+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "double.h" -+#include "quad.h" -+ -+double _Q_qtod(const long double a) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); -+ FP_DECL_D(R); -+ double r; -+ -+ FP_INIT_ROUNDMODE; -+ FP_UNPACK_SEMIRAW_Q(A, a); -+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q -+ FP_TRUNC(D,Q,2,4,R,A); -+#else -+ FP_TRUNC(D,Q,1,2,R,A); -+#endif -+ FP_PACK_SEMIRAW_D(r, R); -+ FP_HANDLE_EXCEPTIONS; -+ -+ return r; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoi.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoi.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoi.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoi.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,38 @@ -+/* Software floating-point emulation. -+ Return (int)a -+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#define FP_ROUNDMODE FP_RND_ZERO -+#include "soft-fp.h" -+#include "quad.h" -+ -+int _Q_qtoi(const long double a) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); -+ unsigned int r; -+ -+ FP_UNPACK_RAW_Q(A, a); -+ FP_TO_INT_Q(r, A, 32, 1); -+ FP_HANDLE_EXCEPTIONS; -+ -+ return r; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoll.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoll.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoll.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoll.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,38 @@ -+/* Software floating-point emulation. -+ Return (long long)a -+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#define FP_ROUNDMODE FP_RND_ZERO -+#include "soft-fp.h" -+#include "quad.h" -+ -+long long _Q_qtoll(const long double a) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); -+ unsigned long long r; -+ -+ FP_UNPACK_RAW_Q(A, a); -+ FP_TO_INT_Q(r, A, 64, 1); -+ FP_HANDLE_EXCEPTIONS; -+ -+ return r; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtos.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtos.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtos.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtos.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,45 @@ -+/* Software floating-point emulation. -+ Return (float)a -+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "single.h" -+#include "quad.h" -+ -+float _Q_qtos(const long double a) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); -+ FP_DECL_S(R); -+ float r; -+ -+ FP_INIT_ROUNDMODE; -+ FP_UNPACK_SEMIRAW_Q(A, a); -+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q -+ FP_TRUNC(S,Q,1,4,R,A); -+#else -+ FP_TRUNC(S,Q,1,2,R,A); -+#endif -+ FP_PACK_SEMIRAW_S(r, R); -+ FP_HANDLE_EXCEPTIONS; -+ -+ return r; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtou.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtou.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtou.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtou.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,38 @@ -+/* Software floating-point emulation. -+ Return (unsigned int)a -+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#define FP_ROUNDMODE FP_RND_ZERO -+#include "soft-fp.h" -+#include "quad.h" -+ -+unsigned int _Q_qtou(const long double a) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); -+ unsigned int r; -+ -+ FP_UNPACK_RAW_Q(A, a); -+ FP_TO_INT_Q(r, A, 32, -1); -+ FP_HANDLE_EXCEPTIONS; -+ -+ return r; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoull.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoull.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoull.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoull.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,38 @@ -+/* Software floating-point emulation. -+ Return (unsigned long long)a -+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#define FP_ROUNDMODE FP_RND_ZERO -+#include "soft-fp.h" -+#include "quad.h" -+ -+unsigned long long _Q_qtoull(const long double a) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); -+ unsigned long long r; -+ -+ FP_UNPACK_RAW_Q(A, a); -+ FP_TO_INT_Q(r, A, 64, -1); -+ FP_HANDLE_EXCEPTIONS; -+ -+ return r; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_sqrt.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_sqrt.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_sqrt.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_sqrt.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,39 @@ -+/* Software floating-point emulation. -+ Return sqrtl(a) -+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+long double _Q_sqrt(const long double a) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); FP_DECL_Q(C); -+ long double c; -+ -+ FP_INIT_ROUNDMODE; -+ FP_UNPACK_Q(A, a); -+ FP_SQRT_Q(C, A); -+ FP_PACK_Q(c, C); -+ FP_HANDLE_EXCEPTIONS; -+ return c; -+} -+strong_alias (_Q_sqrt, __ieee754_sqrtl); -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_stoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_stoq.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_stoq.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_stoq.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,43 @@ -+/* Software floating-point emulation. -+ c = (long double)(a) -+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "single.h" -+#include "quad.h" -+ -+long double _Q_stoq(const float a) -+{ -+ FP_DECL_EX; -+ FP_DECL_S(A); -+ FP_DECL_Q(C); -+ long double c; -+ -+ FP_UNPACK_RAW_S(A, a); -+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q -+ FP_EXTEND(Q,S,4,1,C,A); -+#else -+ FP_EXTEND(Q,S,2,1,C,A); -+#endif -+ FP_PACK_RAW_Q(c, C); -+ FP_HANDLE_EXCEPTIONS; -+ return c; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_sub.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_sub.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_sub.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_sub.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,39 @@ -+/* Software floating-point emulation. -+ c = a - b -+ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+long double _Q_sub(const long double a, const long double b) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); -+ long double c; -+ -+ FP_INIT_ROUNDMODE; -+ FP_UNPACK_SEMIRAW_Q(A, a); -+ FP_UNPACK_SEMIRAW_Q(B, b); -+ FP_SUB_Q(C, A, B); -+ FP_PACK_SEMIRAW_Q(c, C); -+ FP_HANDLE_EXCEPTIONS; -+ return c; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_ulltoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_ulltoq.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_ulltoq.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_ulltoq.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,38 @@ -+/* Software floating-point emulation. -+ Return (long double)(a) -+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+long double _Q_ulltoq(const unsigned long long a) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(C); -+ long double c; -+ unsigned long long b = a; -+ -+ FP_FROM_INT_Q(C, b, 64, unsigned long long); -+ FP_PACK_RAW_Q(c, C); -+ FP_CLEAR_EXCEPTIONS; -+ FP_HANDLE_EXCEPTIONS; -+ return c; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_util.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_util.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_util.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_util.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,57 @@ -+/* Software floating-point emulation. -+ Helper routine for _Q_* routines. -+ Simulate exceptions using double arithmetics. -+ Copyright (C) 1999 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+ -+unsigned long long ___Q_numbers [] = { -+0x0000000000000000ULL, /* Zero */ -+0x0010100000000000ULL, /* Very tiny number */ -+0x0010000000000000ULL, /* Minimum normalized number */ -+0x7fef000000000000ULL, /* A huge double number */ -+}; -+ -+double ___Q_simulate_exceptions(int exceptions) -+{ -+ double d, *p = (double *)___Q_numbers; -+ if (exceptions & FP_EX_INVALID) -+ d = p[0]/p[0]; -+ if (exceptions & FP_EX_OVERFLOW) -+ { -+ d = p[3] + p[3]; -+ exceptions &= ~FP_EX_INEXACT; -+ } -+ if (exceptions & FP_EX_UNDERFLOW) -+ { -+ if (exceptions & FP_EX_INEXACT) -+ { -+ d = p[2] * p[2]; -+ exceptions &= ~FP_EX_INEXACT; -+ } -+ else -+ d = p[1] - p[2]; -+ } -+ if (exceptions & FP_EX_DIVZERO) -+ d = 1.0/p[0]; -+ if (exceptions & FP_EX_INEXACT) -+ d = p[3] - p[2]; -+ return d; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_utoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_utoq.c ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_utoq.c 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_utoq.c 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,38 @@ -+/* Software floating-point emulation. -+ c = (long double)(a) -+ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com) and -+ Jakub Jelinek (jj@ultra.linux.cz). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include "soft-fp.h" -+#include "quad.h" -+ -+long double _Q_utoq(const unsigned int a) -+{ -+ FP_DECL_EX; -+ FP_DECL_Q(C); -+ long double c; -+ unsigned int b = a; -+ -+ FP_FROM_INT_Q(C, b, 32, unsigned int); -+ FP_PACK_RAW_Q(c, C); -+ FP_CLEAR_EXCEPTIONS; -+ FP_HANDLE_EXCEPTIONS; -+ return c; -+} -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/quad.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/quad.h ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/quad.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/quad.h 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,271 @@ -+/* Software floating-point emulation. -+ Definitions for IEEE Quad Precision. -+ Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com), -+ Jakub Jelinek (jj@ultra.linux.cz), -+ David S. Miller (davem@redhat.com) and -+ Peter Maydell (pmaydell@chiark.greenend.org.uk). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ In addition to the permissions in the GNU Lesser General Public -+ License, the Free Software Foundation gives you unlimited -+ permission to link the compiled version of this file into -+ combinations with other programs, and to distribute those -+ combinations without any restriction coming from the use of this -+ file. (The Lesser General Public License restrictions do apply in -+ other respects; for example, they cover modification of the file, -+ and distribution when not linked into a combine executable.) -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -+ MA 02110-1301, USA. */ -+ -+#if _FP_W_TYPE_SIZE < 32 -+#error "Here's a nickel, kid. Go buy yourself a real computer." -+#endif -+ -+#if _FP_W_TYPE_SIZE < 64 -+#define _FP_FRACTBITS_Q (4*_FP_W_TYPE_SIZE) -+#else -+#define _FP_FRACTBITS_Q (2*_FP_W_TYPE_SIZE) -+#endif -+ -+#define _FP_FRACBITS_Q 113 -+#define _FP_FRACXBITS_Q (_FP_FRACTBITS_Q - _FP_FRACBITS_Q) -+#define _FP_WFRACBITS_Q (_FP_WORKBITS + _FP_FRACBITS_Q) -+#define _FP_WFRACXBITS_Q (_FP_FRACTBITS_Q - _FP_WFRACBITS_Q) -+#define _FP_EXPBITS_Q 15 -+#define _FP_EXPBIAS_Q 16383 -+#define _FP_EXPMAX_Q 32767 -+ -+#define _FP_QNANBIT_Q \ -+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2) % _FP_W_TYPE_SIZE) -+#define _FP_QNANBIT_SH_Q \ -+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) -+#define _FP_IMPLBIT_Q \ -+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1) % _FP_W_TYPE_SIZE) -+#define _FP_IMPLBIT_SH_Q \ -+ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) -+#define _FP_OVERFLOW_Q \ -+ ((_FP_W_TYPE)1 << (_FP_WFRACBITS_Q % _FP_W_TYPE_SIZE)) -+ -+typedef float TFtype __attribute__((mode(TF))); -+ -+#if _FP_W_TYPE_SIZE < 64 -+ -+union _FP_UNION_Q -+{ -+ TFtype flt; -+ struct -+ { -+#if __BYTE_ORDER == __BIG_ENDIAN -+ unsigned sign : 1; -+ unsigned exp : _FP_EXPBITS_Q; -+ unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); -+ unsigned long frac2 : _FP_W_TYPE_SIZE; -+ unsigned long frac1 : _FP_W_TYPE_SIZE; -+ unsigned long frac0 : _FP_W_TYPE_SIZE; -+#else -+ unsigned long frac0 : _FP_W_TYPE_SIZE; -+ unsigned long frac1 : _FP_W_TYPE_SIZE; -+ unsigned long frac2 : _FP_W_TYPE_SIZE; -+ unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); -+ unsigned exp : _FP_EXPBITS_Q; -+ unsigned sign : 1; -+#endif /* not bigendian */ -+ } bits __attribute__((packed)); -+}; -+ -+ -+#define FP_DECL_Q(X) _FP_DECL(4,X) -+#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_4(Q,X,val) -+#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_4_P(Q,X,val) -+#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_4(Q,val,X) -+#define FP_PACK_RAW_QP(val,X) \ -+ do { \ -+ if (!FP_INHIBIT_RESULTS) \ -+ _FP_PACK_RAW_4_P(Q,val,X); \ -+ } while (0) -+ -+#define FP_UNPACK_Q(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_4(Q,X,val); \ -+ _FP_UNPACK_CANONICAL(Q,4,X); \ -+ } while (0) -+ -+#define FP_UNPACK_QP(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_4_P(Q,X,val); \ -+ _FP_UNPACK_CANONICAL(Q,4,X); \ -+ } while (0) -+ -+#define FP_UNPACK_SEMIRAW_Q(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_4(Q,X,val); \ -+ _FP_UNPACK_SEMIRAW(Q,4,X); \ -+ } while (0) -+ -+#define FP_UNPACK_SEMIRAW_QP(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_4_P(Q,X,val); \ -+ _FP_UNPACK_SEMIRAW(Q,4,X); \ -+ } while (0) -+ -+#define FP_PACK_Q(val,X) \ -+ do { \ -+ _FP_PACK_CANONICAL(Q,4,X); \ -+ _FP_PACK_RAW_4(Q,val,X); \ -+ } while (0) -+ -+#define FP_PACK_QP(val,X) \ -+ do { \ -+ _FP_PACK_CANONICAL(Q,4,X); \ -+ if (!FP_INHIBIT_RESULTS) \ -+ _FP_PACK_RAW_4_P(Q,val,X); \ -+ } while (0) -+ -+#define FP_PACK_SEMIRAW_Q(val,X) \ -+ do { \ -+ _FP_PACK_SEMIRAW(Q,4,X); \ -+ _FP_PACK_RAW_4(Q,val,X); \ -+ } while (0) -+ -+#define FP_PACK_SEMIRAW_QP(val,X) \ -+ do { \ -+ _FP_PACK_SEMIRAW(Q,4,X); \ -+ if (!FP_INHIBIT_RESULTS) \ -+ _FP_PACK_RAW_4_P(Q,val,X); \ -+ } while (0) -+ -+#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,4,X) -+#define FP_NEG_Q(R,X) _FP_NEG(Q,4,R,X) -+#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,4,R,X,Y) -+#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,4,R,X,Y) -+#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,4,R,X,Y) -+#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,4,R,X,Y) -+#define FP_SQRT_Q(R,X) _FP_SQRT(Q,4,R,X) -+#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_4(R,S,T,X,Q) -+ -+#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,4,r,X,Y,un) -+#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,4,r,X,Y) -+#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,4,r,X,Y) -+ -+#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,4,r,X,rsz,rsg) -+#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,4,X,r,rs,rt) -+ -+#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_4(X) -+#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_4(X) -+ -+#else /* not _FP_W_TYPE_SIZE < 64 */ -+union _FP_UNION_Q -+{ -+ TFtype flt /* __attribute__((mode(TF))) */ ; -+ struct { -+ _FP_W_TYPE a, b; -+ } longs; -+ struct { -+#if __BYTE_ORDER == __BIG_ENDIAN -+ unsigned sign : 1; -+ unsigned exp : _FP_EXPBITS_Q; -+ _FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE; -+ _FP_W_TYPE frac0 : _FP_W_TYPE_SIZE; -+#else -+ _FP_W_TYPE frac0 : _FP_W_TYPE_SIZE; -+ _FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE; -+ unsigned exp : _FP_EXPBITS_Q; -+ unsigned sign : 1; -+#endif -+ } bits; -+}; -+ -+#define FP_DECL_Q(X) _FP_DECL(2,X) -+#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_2(Q,X,val) -+#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_2_P(Q,X,val) -+#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_2(Q,val,X) -+#define FP_PACK_RAW_QP(val,X) \ -+ do { \ -+ if (!FP_INHIBIT_RESULTS) \ -+ _FP_PACK_RAW_2_P(Q,val,X); \ -+ } while (0) -+ -+#define FP_UNPACK_Q(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_2(Q,X,val); \ -+ _FP_UNPACK_CANONICAL(Q,2,X); \ -+ } while (0) -+ -+#define FP_UNPACK_QP(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_2_P(Q,X,val); \ -+ _FP_UNPACK_CANONICAL(Q,2,X); \ -+ } while (0) -+ -+#define FP_UNPACK_SEMIRAW_Q(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_2(Q,X,val); \ -+ _FP_UNPACK_SEMIRAW(Q,2,X); \ -+ } while (0) -+ -+#define FP_UNPACK_SEMIRAW_QP(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_2_P(Q,X,val); \ -+ _FP_UNPACK_SEMIRAW(Q,2,X); \ -+ } while (0) -+ -+#define FP_PACK_Q(val,X) \ -+ do { \ -+ _FP_PACK_CANONICAL(Q,2,X); \ -+ _FP_PACK_RAW_2(Q,val,X); \ -+ } while (0) -+ -+#define FP_PACK_QP(val,X) \ -+ do { \ -+ _FP_PACK_CANONICAL(Q,2,X); \ -+ if (!FP_INHIBIT_RESULTS) \ -+ _FP_PACK_RAW_2_P(Q,val,X); \ -+ } while (0) -+ -+#define FP_PACK_SEMIRAW_Q(val,X) \ -+ do { \ -+ _FP_PACK_SEMIRAW(Q,2,X); \ -+ _FP_PACK_RAW_2(Q,val,X); \ -+ } while (0) -+ -+#define FP_PACK_SEMIRAW_QP(val,X) \ -+ do { \ -+ _FP_PACK_SEMIRAW(Q,2,X); \ -+ if (!FP_INHIBIT_RESULTS) \ -+ _FP_PACK_RAW_2_P(Q,val,X); \ -+ } while (0) -+ -+#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,2,X) -+#define FP_NEG_Q(R,X) _FP_NEG(Q,2,R,X) -+#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,2,R,X,Y) -+#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,2,R,X,Y) -+#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,2,R,X,Y) -+#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,2,R,X,Y) -+#define FP_SQRT_Q(R,X) _FP_SQRT(Q,2,R,X) -+#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q) -+ -+#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,2,r,X,Y,un) -+#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,2,r,X,Y) -+#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,2,r,X,Y) -+ -+#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,2,r,X,rsz,rsg) -+#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,2,X,r,rs,rt) -+ -+#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_2(X) -+#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_2(X) -+ -+#endif /* not _FP_W_TYPE_SIZE < 64 */ -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,213 @@ -+/* Machine-dependent software floating-point definitions. -+ Sparc userland (_Q_*) version. -+ Copyright (C) 1997,1998,1999, 2002, 2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com), -+ Jakub Jelinek (jj@ultra.linux.cz) and -+ David S. Miller (davem@redhat.com). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include -+#include -+ -+#define _FP_W_TYPE_SIZE 32 -+#define _FP_W_TYPE unsigned long -+#define _FP_WS_TYPE signed long -+#define _FP_I_TYPE long -+ -+#define _FP_MUL_MEAT_S(R,X,Y) \ -+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) -+#define _FP_MUL_MEAT_D(R,X,Y) \ -+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) -+#define _FP_MUL_MEAT_Q(R,X,Y) \ -+ _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) -+ -+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y) -+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y) -+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y) -+ -+#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1) -+#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1 -+#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1 -+#define _FP_NANSIGN_S 0 -+#define _FP_NANSIGN_D 0 -+#define _FP_NANSIGN_Q 0 -+ -+#define _FP_KEEPNANFRACP 1 -+ -+/* If one NaN is signaling and the other is not, -+ * we choose that one, otherwise we choose X. -+ */ -+/* For _Qp_* and _Q_*, this should prefer X, for -+ * CPU instruction emulation this should prefer Y. -+ * (see SPAMv9 B.2.2 section). -+ */ -+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ -+ do { \ -+ if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \ -+ && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \ -+ { \ -+ R##_s = Y##_s; \ -+ _FP_FRAC_COPY_##wc(R,Y); \ -+ } \ -+ else \ -+ { \ -+ R##_s = X##_s; \ -+ _FP_FRAC_COPY_##wc(R,X); \ -+ } \ -+ R##_c = FP_CLS_NAN; \ -+ } while (0) -+ -+/* Some assembly to speed things up. */ -+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ -+ __asm__ ("addcc %r7,%8,%2\n\ -+ addxcc %r5,%6,%1\n\ -+ addx %r3,%4,%0" \ -+ : "=r" ((USItype)(r2)), \ -+ "=&r" ((USItype)(r1)), \ -+ "=&r" ((USItype)(r0)) \ -+ : "%rJ" ((USItype)(x2)), \ -+ "rI" ((USItype)(y2)), \ -+ "%rJ" ((USItype)(x1)), \ -+ "rI" ((USItype)(y1)), \ -+ "%rJ" ((USItype)(x0)), \ -+ "rI" ((USItype)(y0)) \ -+ : "cc") -+ -+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ -+ __asm__ ("subcc %r7,%8,%2\n\ -+ subxcc %r5,%6,%1\n\ -+ subx %r3,%4,%0" \ -+ : "=r" ((USItype)(r2)), \ -+ "=&r" ((USItype)(r1)), \ -+ "=&r" ((USItype)(r0)) \ -+ : "%rJ" ((USItype)(x2)), \ -+ "rI" ((USItype)(y2)), \ -+ "%rJ" ((USItype)(x1)), \ -+ "rI" ((USItype)(y1)), \ -+ "%rJ" ((USItype)(x0)), \ -+ "rI" ((USItype)(y0)) \ -+ : "cc") -+ -+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ -+ do { \ -+ /* We need to fool gcc, as we need to pass more than 10 \ -+ input/outputs. */ \ -+ register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2"); \ -+ __asm__ __volatile__ ("\ -+ addcc %r8,%9,%1\n\ -+ addxcc %r6,%7,%0\n\ -+ addxcc %r4,%5,%%g2\n\ -+ addx %r2,%3,%%g1" \ -+ : "=&r" ((USItype)(r1)), \ -+ "=&r" ((USItype)(r0)) \ -+ : "%rJ" ((USItype)(x3)), \ -+ "rI" ((USItype)(y3)), \ -+ "%rJ" ((USItype)(x2)), \ -+ "rI" ((USItype)(y2)), \ -+ "%rJ" ((USItype)(x1)), \ -+ "rI" ((USItype)(y1)), \ -+ "%rJ" ((USItype)(x0)), \ -+ "rI" ((USItype)(y0)) \ -+ : "cc", "g1", "g2"); \ -+ __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2)); \ -+ r3 = _t1; r2 = _t2; \ -+ } while (0) -+ -+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ -+ do { \ -+ /* We need to fool gcc, as we need to pass more than 10 \ -+ input/outputs. */ \ -+ register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2"); \ -+ __asm__ __volatile__ ("\ -+ subcc %r8,%9,%1\n\ -+ subxcc %r6,%7,%0\n\ -+ subxcc %r4,%5,%%g2\n\ -+ subx %r2,%3,%%g1" \ -+ : "=&r" ((USItype)(r1)), \ -+ "=&r" ((USItype)(r0)) \ -+ : "%rJ" ((USItype)(x3)), \ -+ "rI" ((USItype)(y3)), \ -+ "%rJ" ((USItype)(x2)), \ -+ "rI" ((USItype)(y2)), \ -+ "%rJ" ((USItype)(x1)), \ -+ "rI" ((USItype)(y1)), \ -+ "%rJ" ((USItype)(x0)), \ -+ "rI" ((USItype)(y0)) \ -+ : "cc", "g1", "g2"); \ -+ __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2)); \ -+ r3 = _t1; r2 = _t2; \ -+ } while (0) -+ -+#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0) -+ -+#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0) -+ -+#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \ -+ __asm__ ("addcc %3,%4,%3\n\ -+ addxcc %2,%%g0,%2\n\ -+ addxcc %1,%%g0,%1\n\ -+ addx %0,%%g0,%0" \ -+ : "=&r" ((USItype)(x3)), \ -+ "=&r" ((USItype)(x2)), \ -+ "=&r" ((USItype)(x1)), \ -+ "=&r" ((USItype)(x0)) \ -+ : "rI" ((USItype)(i)), \ -+ "0" ((USItype)(x3)), \ -+ "1" ((USItype)(x2)), \ -+ "2" ((USItype)(x1)), \ -+ "3" ((USItype)(x0)) \ -+ : "cc") -+ -+/* Obtain the current rounding mode. */ -+#ifndef FP_ROUNDMODE -+#define FP_ROUNDMODE ((_fcw >> 30) & 0x3) -+#endif -+ -+/* Exception flags. */ -+#define FP_EX_INVALID (1 << 4) -+#define FP_EX_OVERFLOW (1 << 3) -+#define FP_EX_UNDERFLOW (1 << 2) -+#define FP_EX_DIVZERO (1 << 1) -+#define FP_EX_INEXACT (1 << 0) -+ -+#define _FP_DECL_EX fpu_control_t _fcw -+ -+#define FP_INIT_ROUNDMODE \ -+do { \ -+ _FPU_GETCW(_fcw); \ -+} while (0) -+ -+/* Simulate exceptions using double arithmetics. */ -+extern double ___Q_simulate_exceptions(int exc); -+ -+#define FP_HANDLE_EXCEPTIONS \ -+do { \ -+ if (!_fex) \ -+ { \ -+ /* This is the common case, so we do it inline. \ -+ * We need to clear cexc bits if any. \ -+ */ \ -+ extern unsigned long long ___Q_numbers[]; \ -+ __asm__ __volatile__("\ -+ ldd [%0], %%f30\n\ -+ faddd %%f30, %%f30, %%f30\ -+ " : : "r" (___Q_numbers) : "f30"); \ -+ } \ -+ else \ -+ ___Q_simulate_exceptions (_fex); \ -+} while (0) -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/single.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/single.h ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/single.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/single.h 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,151 @@ -+/* Software floating-point emulation. -+ Definitions for IEEE Single Precision. -+ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com), -+ Jakub Jelinek (jj@ultra.linux.cz), -+ David S. Miller (davem@redhat.com) and -+ Peter Maydell (pmaydell@chiark.greenend.org.uk). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ In addition to the permissions in the GNU Lesser General Public -+ License, the Free Software Foundation gives you unlimited -+ permission to link the compiled version of this file into -+ combinations with other programs, and to distribute those -+ combinations without any restriction coming from the use of this -+ file. (The Lesser General Public License restrictions do apply in -+ other respects; for example, they cover modification of the file, -+ and distribution when not linked into a combine executable.) -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -+ MA 02110-1301, USA. */ -+ -+#if _FP_W_TYPE_SIZE < 32 -+#error "Here's a nickel kid. Go buy yourself a real computer." -+#endif -+ -+#define _FP_FRACTBITS_S _FP_W_TYPE_SIZE -+ -+#define _FP_FRACBITS_S 24 -+#define _FP_FRACXBITS_S (_FP_FRACTBITS_S - _FP_FRACBITS_S) -+#define _FP_WFRACBITS_S (_FP_WORKBITS + _FP_FRACBITS_S) -+#define _FP_WFRACXBITS_S (_FP_FRACTBITS_S - _FP_WFRACBITS_S) -+#define _FP_EXPBITS_S 8 -+#define _FP_EXPBIAS_S 127 -+#define _FP_EXPMAX_S 255 -+#define _FP_QNANBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2)) -+#define _FP_QNANBIT_SH_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2+_FP_WORKBITS)) -+#define _FP_IMPLBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1)) -+#define _FP_IMPLBIT_SH_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1+_FP_WORKBITS)) -+#define _FP_OVERFLOW_S ((_FP_W_TYPE)1 << (_FP_WFRACBITS_S)) -+ -+/* The implementation of _FP_MUL_MEAT_S and _FP_DIV_MEAT_S should be -+ chosen by the target machine. */ -+ -+typedef float SFtype __attribute__((mode(SF))); -+ -+union _FP_UNION_S -+{ -+ SFtype flt; -+ struct { -+#if __BYTE_ORDER == __BIG_ENDIAN -+ unsigned sign : 1; -+ unsigned exp : _FP_EXPBITS_S; -+ unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0); -+#else -+ unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0); -+ unsigned exp : _FP_EXPBITS_S; -+ unsigned sign : 1; -+#endif -+ } bits __attribute__((packed)); -+}; -+ -+#define FP_DECL_S(X) _FP_DECL(1,X) -+#define FP_UNPACK_RAW_S(X,val) _FP_UNPACK_RAW_1(S,X,val) -+#define FP_UNPACK_RAW_SP(X,val) _FP_UNPACK_RAW_1_P(S,X,val) -+#define FP_PACK_RAW_S(val,X) _FP_PACK_RAW_1(S,val,X) -+#define FP_PACK_RAW_SP(val,X) \ -+ do { \ -+ if (!FP_INHIBIT_RESULTS) \ -+ _FP_PACK_RAW_1_P(S,val,X); \ -+ } while (0) -+ -+#define FP_UNPACK_S(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_1(S,X,val); \ -+ _FP_UNPACK_CANONICAL(S,1,X); \ -+ } while (0) -+ -+#define FP_UNPACK_SP(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_1_P(S,X,val); \ -+ _FP_UNPACK_CANONICAL(S,1,X); \ -+ } while (0) -+ -+#define FP_UNPACK_SEMIRAW_S(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_1(S,X,val); \ -+ _FP_UNPACK_SEMIRAW(S,1,X); \ -+ } while (0) -+ -+#define FP_UNPACK_SEMIRAW_SP(X,val) \ -+ do { \ -+ _FP_UNPACK_RAW_1_P(S,X,val); \ -+ _FP_UNPACK_SEMIRAW(S,1,X); \ -+ } while (0) -+ -+#define FP_PACK_S(val,X) \ -+ do { \ -+ _FP_PACK_CANONICAL(S,1,X); \ -+ _FP_PACK_RAW_1(S,val,X); \ -+ } while (0) -+ -+#define FP_PACK_SP(val,X) \ -+ do { \ -+ _FP_PACK_CANONICAL(S,1,X); \ -+ if (!FP_INHIBIT_RESULTS) \ -+ _FP_PACK_RAW_1_P(S,val,X); \ -+ } while (0) -+ -+#define FP_PACK_SEMIRAW_S(val,X) \ -+ do { \ -+ _FP_PACK_SEMIRAW(S,1,X); \ -+ _FP_PACK_RAW_1(S,val,X); \ -+ } while (0) -+ -+#define FP_PACK_SEMIRAW_SP(val,X) \ -+ do { \ -+ _FP_PACK_SEMIRAW(S,1,X); \ -+ if (!FP_INHIBIT_RESULTS) \ -+ _FP_PACK_RAW_1_P(S,val,X); \ -+ } while (0) -+ -+#define FP_ISSIGNAN_S(X) _FP_ISSIGNAN(S,1,X) -+#define FP_NEG_S(R,X) _FP_NEG(S,1,R,X) -+#define FP_ADD_S(R,X,Y) _FP_ADD(S,1,R,X,Y) -+#define FP_SUB_S(R,X,Y) _FP_SUB(S,1,R,X,Y) -+#define FP_MUL_S(R,X,Y) _FP_MUL(S,1,R,X,Y) -+#define FP_DIV_S(R,X,Y) _FP_DIV(S,1,R,X,Y) -+#define FP_SQRT_S(R,X) _FP_SQRT(S,1,R,X) -+#define _FP_SQRT_MEAT_S(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q) -+ -+#define FP_CMP_S(r,X,Y,un) _FP_CMP(S,1,r,X,Y,un) -+#define FP_CMP_EQ_S(r,X,Y) _FP_CMP_EQ(S,1,r,X,Y) -+#define FP_CMP_UNORD_S(r,X,Y) _FP_CMP_UNORD(S,1,r,X,Y) -+ -+#define FP_TO_INT_S(r,X,rsz,rsg) _FP_TO_INT(S,1,r,X,rsz,rsg) -+#define FP_FROM_INT_S(X,r,rs,rt) _FP_FROM_INT(S,1,X,r,rs,rt) -+ -+#define _FP_FRAC_HIGH_S(X) _FP_FRAC_HIGH_1(X) -+#define _FP_FRAC_HIGH_RAW_S(X) _FP_FRAC_HIGH_1(X) -diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/soft-fp.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/soft-fp.h ---- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/soft-fp.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/soft-fp.h 2010-10-14 14:05:37.000000000 +0200 -@@ -0,0 +1,205 @@ -+/* Software floating-point emulation. -+ Copyright (C) 1997,1998,1999,2000,2002,2003,2005,2006,2007 -+ Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Richard Henderson (rth@cygnus.com), -+ Jakub Jelinek (jj@ultra.linux.cz), -+ David S. Miller (davem@redhat.com) and -+ Peter Maydell (pmaydell@chiark.greenend.org.uk). -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ In addition to the permissions in the GNU Lesser General Public -+ License, the Free Software Foundation gives you unlimited -+ permission to link the compiled version of this file into -+ combinations with other programs, and to distribute those -+ combinations without any restriction coming from the use of this -+ file. (The Lesser General Public License restrictions do apply in -+ other respects; for example, they cover modification of the file, -+ and distribution when not linked into a combine executable.) -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -+ MA 02110-1301, USA. */ -+ -+#ifndef SOFT_FP_H -+#define SOFT_FP_H -+ -+#include "sfp-machine.h" -+ -+/* Allow sfp-machine to have its own byte order definitions. */ -+#ifndef __BYTE_ORDER -+#ifdef _LIBC -+#include -+#else -+#error "endianness not defined by sfp-machine.h" -+#endif -+#endif -+ -+#define _FP_WORKBITS 3 -+#define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3) -+#define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2) -+#define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1) -+#define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0) -+ -+#ifndef FP_RND_NEAREST -+# define FP_RND_NEAREST 0 -+# define FP_RND_ZERO 1 -+# define FP_RND_PINF 2 -+# define FP_RND_MINF 3 -+#endif -+#ifndef FP_ROUNDMODE -+# define FP_ROUNDMODE FP_RND_NEAREST -+#endif -+ -+/* By default don't care about exceptions. */ -+#ifndef FP_EX_INVALID -+#define FP_EX_INVALID 0 -+#endif -+#ifndef FP_EX_OVERFLOW -+#define FP_EX_OVERFLOW 0 -+#endif -+#ifndef FP_EX_UNDERFLOW -+#define FP_EX_UNDERFLOW 0 -+#endif -+#ifndef FP_EX_DIVZERO -+#define FP_EX_DIVZERO 0 -+#endif -+#ifndef FP_EX_INEXACT -+#define FP_EX_INEXACT 0 -+#endif -+#ifndef FP_EX_DENORM -+#define FP_EX_DENORM 0 -+#endif -+ -+#ifdef _FP_DECL_EX -+#define FP_DECL_EX \ -+ int _fex = 0; \ -+ _FP_DECL_EX -+#else -+#define FP_DECL_EX int _fex = 0 -+#endif -+ -+#ifndef FP_INIT_ROUNDMODE -+#define FP_INIT_ROUNDMODE do {} while (0) -+#endif -+ -+#ifndef FP_HANDLE_EXCEPTIONS -+#define FP_HANDLE_EXCEPTIONS do {} while (0) -+#endif -+ -+#ifndef FP_INHIBIT_RESULTS -+/* By default we write the results always. -+ * sfp-machine may override this and e.g. -+ * check if some exceptions are unmasked -+ * and inhibit it in such a case. -+ */ -+#define FP_INHIBIT_RESULTS 0 -+#endif -+ -+#define FP_SET_EXCEPTION(ex) \ -+ _fex |= (ex) -+ -+#define FP_UNSET_EXCEPTION(ex) \ -+ _fex &= ~(ex) -+ -+#define FP_CLEAR_EXCEPTIONS \ -+ _fex = 0 -+ -+#define _FP_ROUND_NEAREST(wc, X) \ -+do { \ -+ if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND) \ -+ _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \ -+} while (0) -+ -+#define _FP_ROUND_ZERO(wc, X) (void)0 -+ -+#define _FP_ROUND_PINF(wc, X) \ -+do { \ -+ if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ -+ _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ -+} while (0) -+ -+#define _FP_ROUND_MINF(wc, X) \ -+do { \ -+ if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ -+ _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ -+} while (0) -+ -+#define _FP_ROUND(wc, X) \ -+do { \ -+ if (_FP_FRAC_LOW_##wc(X) & 7) \ -+ FP_SET_EXCEPTION(FP_EX_INEXACT); \ -+ switch (FP_ROUNDMODE) \ -+ { \ -+ case FP_RND_NEAREST: \ -+ _FP_ROUND_NEAREST(wc,X); \ -+ break; \ -+ case FP_RND_ZERO: \ -+ _FP_ROUND_ZERO(wc,X); \ -+ break; \ -+ case FP_RND_PINF: \ -+ _FP_ROUND_PINF(wc,X); \ -+ break; \ -+ case FP_RND_MINF: \ -+ _FP_ROUND_MINF(wc,X); \ -+ break; \ -+ } \ -+} while (0) -+ -+#define FP_CLS_NORMAL 0 -+#define FP_CLS_ZERO 1 -+#define FP_CLS_INF 2 -+#define FP_CLS_NAN 3 -+ -+#define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y)) -+ -+#include "op-1.h" -+#include "op-2.h" -+#include "op-4.h" -+#include "op-8.h" -+#include "op-common.h" -+ -+/* Sigh. Silly things longlong.h needs. */ -+#define UWtype _FP_W_TYPE -+#define W_TYPE_SIZE _FP_W_TYPE_SIZE -+ -+typedef int QItype __attribute__((mode(QI))); -+typedef int SItype __attribute__((mode(SI))); -+typedef int DItype __attribute__((mode(DI))); -+typedef unsigned int UQItype __attribute__((mode(QI))); -+typedef unsigned int USItype __attribute__((mode(SI))); -+typedef unsigned int UDItype __attribute__((mode(DI))); -+#if _FP_W_TYPE_SIZE == 32 -+typedef unsigned int UHWtype __attribute__((mode(HI))); -+#elif _FP_W_TYPE_SIZE == 64 -+typedef USItype UHWtype; -+#endif -+ -+#ifndef CMPtype -+#define CMPtype int -+#endif -+ -+#define SI_BITS (__CHAR_BIT__ * (int)sizeof(SItype)) -+#define DI_BITS (__CHAR_BIT__ * (int)sizeof(DItype)) -+ -+#ifndef umul_ppmm -+#include "longlong.h" -+#endif -+ -+#ifdef _LIBC -+#include -+#else -+extern void abort (void); -+#endif -+ -+#endif diff --git a/toolchain/uClibc/uClibc-0.9.31-workaround-GCC-PR32219.patch b/toolchain/uClibc/uClibc-0.9.31-workaround-GCC-PR32219.patch deleted file mode 100644 index 242a5264b8..0000000000 --- a/toolchain/uClibc/uClibc-0.9.31-workaround-GCC-PR32219.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 2e53dd645d5348f207cec7f8595969dc566c5a55 Mon Sep 17 00:00:00 2001 -From: Denys Vlasenko -Date: Mon, 17 May 2010 15:56:19 +0200 -Subject: [PATCH] workaround GCC PR32219 - -we ended up calling 0 -Fixes bug #1033 - -Signed-off-by: Denys Vlasenko -Signed-off-by: Bernhard Reutner-Fischer ---- - libc/misc/internals/__uClibc_main.c | 15 +++++++++++++-- - 1 files changed, 13 insertions(+), 2 deletions(-) - -diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c -index f9e1244..4ee4443 100644 ---- a/libc/misc/internals/__uClibc_main.c -+++ b/libc/misc/internals/__uClibc_main.c -@@ -105,6 +105,17 @@ _pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer *__buffer, - - #endif /* !SHARED */ - -+/* Defeat compiler optimization which assumes function addresses are never NULL */ -+static __always_inline int not_null_ptr(const void *p) -+{ -+ const void *q; -+ __asm__ ("" -+ : "=r" (q) /* output */ -+ : "0" (p) /* input */ -+ ); -+ return q != 0; -+} -+ - /* - * Prototypes. - */ -@@ -254,7 +265,7 @@ void __uClibc_init(void) - - #ifdef __UCLIBC_HAS_LOCALE__ - /* Initialize the global locale structure. */ -- if (likely(_locale_init!=NULL)) -+ if (likely(not_null_ptr(_locale_init))) - _locale_init(); - #endif - -@@ -264,7 +275,7 @@ void __uClibc_init(void) - * Thus we get a nice size savings because the stdio functions - * won't be pulled into the final static binary unless used. - */ -- if (likely(_stdio_init != NULL)) -+ if (likely(not_null_ptr(_stdio_init))) - _stdio_init(); - - } --- -1.7.1 - diff --git a/toolchain/uClibc/uClibc-0.9.31.1-add-bsd-endian-conversions.patch b/toolchain/uClibc/uClibc-0.9.31.1-add-bsd-endian-conversions.patch new file mode 100644 index 0000000000..652d7c9f10 --- /dev/null +++ b/toolchain/uClibc/uClibc-0.9.31.1-add-bsd-endian-conversions.patch @@ -0,0 +1,64 @@ +From c6d6237819037168a6923ac080e348e54615422c Mon Sep 17 00:00:00 2001 +From: Vladimir Zapolskiy +Date: Tue, 1 Jun 2010 23:22:57 +0400 +Subject: [PATCH] endian.h: add BSD convertions between big/little-endian byte order + +This patch adds support for convertion of values between host and +big-/little-endian byte order. + +Signed-off-by: Vladimir Zapolskiy +Signed-off-by: Bernhard Reutner-Fischer +--- + include/endian.h | 38 ++++++++++++++++++++++++++++++++++++++ + 1 files changed, 38 insertions(+), 0 deletions(-) + +diff --git a/include/endian.h b/include/endian.h +index 2f7bce1..0ba7384 100644 +--- a/include/endian.h ++++ b/include/endian.h +@@ -55,4 +55,42 @@ + # define __LONG_LONG_PAIR(HI, LO) HI, LO + #endif + ++ ++#ifdef __USE_BSD ++/* Conversion interfaces. */ ++# include ++ ++# if __BYTE_ORDER == __LITTLE_ENDIAN ++# define htobe16(x) __bswap_16 (x) ++# define htole16(x) (x) ++# define be16toh(x) __bswap_16 (x) ++# define le16toh(x) (x) ++ ++# define htobe32(x) __bswap_32 (x) ++# define htole32(x) (x) ++# define be32toh(x) __bswap_32 (x) ++# define le32toh(x) (x) ++ ++# define htobe64(x) __bswap_64 (x) ++# define htole64(x) (x) ++# define be64toh(x) __bswap_64 (x) ++# define le64toh(x) (x) ++# else ++# define htobe16(x) (x) ++# define htole16(x) __bswap_16 (x) ++# define be16toh(x) (x) ++# define le16toh(x) __bswap_16 (x) ++ ++# define htobe32(x) (x) ++# define htole32(x) __bswap_32 (x) ++# define be32toh(x) (x) ++# define le32toh(x) __bswap_32 (x) ++ ++# define htobe64(x) (x) ++# define htole64(x) __bswap_64 (x) ++# define be64toh(x) (x) ++# define le64toh(x) __bswap_64 (x) ++# endif ++#endif ++ + #endif /* endian.h */ +-- +1.7.3.4 + diff --git a/toolchain/uClibc/uClibc-0.9.31.1-add-inotify-init1.patch b/toolchain/uClibc/uClibc-0.9.31.1-add-inotify-init1.patch new file mode 100644 index 0000000000..cbec426238 --- /dev/null +++ b/toolchain/uClibc/uClibc-0.9.31.1-add-inotify-init1.patch @@ -0,0 +1,64 @@ +From a2e5630af426f85fdd8721b2820786d9bd2aa695 Mon Sep 17 00:00:00 2001 +From: Vladimir Zapolskiy +Date: Tue, 1 Jun 2010 20:02:54 +0400 +Subject: [PATCH] inotify: add inotify_init1 system call support + +This patch introduces support for inotify_init1 system call, found +since Linux 2.6.27. + +Signed-off-by: Vladimir Zapolskiy +Signed-off-by: Khem Raj +--- + libc/sysdeps/linux/common/inotify.c | 4 ++++ + libc/sysdeps/linux/common/sys/inotify.h | 13 +++++++++++++ + 2 files changed, 17 insertions(+), 0 deletions(-) + +diff --git a/libc/sysdeps/linux/common/inotify.c b/libc/sysdeps/linux/common/inotify.c +index e5a6120..e35f043 100644 +--- a/libc/sysdeps/linux/common/inotify.c ++++ b/libc/sysdeps/linux/common/inotify.c +@@ -15,6 +15,10 @@ + _syscall0(int, inotify_init) + #endif + ++#ifdef __NR_inotify_init1 ++_syscall1(int, inotify_init1, int, flags) ++#endif ++ + #ifdef __NR_inotify_add_watch + _syscall3(int, inotify_add_watch, int, fd, const char *, path, uint32_t, mask) + #endif +diff --git a/libc/sysdeps/linux/common/sys/inotify.h b/libc/sysdeps/linux/common/sys/inotify.h +index 0131db9..dc4e19d 100644 +--- a/libc/sysdeps/linux/common/sys/inotify.h ++++ b/libc/sysdeps/linux/common/sys/inotify.h +@@ -22,6 +22,16 @@ + #include + + ++/* Flags for the parameter of inotify_init1. */ ++enum ++ { ++ IN_CLOEXEC = 02000000, ++#define IN_CLOEXEC IN_CLOEXEC ++ IN_NONBLOCK = 04000 ++#define IN_NONBLOCK IN_NONBLOCK ++ }; ++ ++ + /* Structure describing an inotify event. */ + struct inotify_event + { +@@ -79,6 +89,9 @@ __BEGIN_DECLS + /* Create and initialize inotify instance. */ + extern int inotify_init (void) __THROW; + ++/* Create and initialize inotify instance. */ ++extern int inotify_init1 (int __flags) __THROW; ++ + /* Add watch of object NAME to inotify instance FD. Notify about + events specified by MASK. */ + extern int inotify_add_watch (int __fd, const char *__name, uint32_t __mask) +-- +1.7.3.4 + diff --git a/toolchain/uClibc/uClibc-0.9.31.1-add-sock-cloexec.patch b/toolchain/uClibc/uClibc-0.9.31.1-add-sock-cloexec.patch new file mode 100644 index 0000000000..a7089a98ac --- /dev/null +++ b/toolchain/uClibc/uClibc-0.9.31.1-add-sock-cloexec.patch @@ -0,0 +1,43 @@ +From 83333e9c873e4eca6b2c945f7770b1f5373b0427 Mon Sep 17 00:00:00 2001 +From: Vladimir Zapolskiy +Date: Tue, 1 Jun 2010 20:02:39 +0400 +Subject: [PATCH] bits/socket.h: add SOCK_CLOEXEC and SOCK_NONBLOCK support + +This patch adds support for SOCK_CLOEXEC and SOCK_NONBLOCK socket +descriptor flags, which are introduced since Linux 2.6.27 + +Signed-off-by: Vladimir Zapolskiy +Signed-off-by: Khem Raj +--- + libc/sysdeps/linux/common/bits/socket.h | 12 +++++++++++- + 1 files changed, 11 insertions(+), 1 deletions(-) + +diff --git a/libc/sysdeps/linux/common/bits/socket.h b/libc/sysdeps/linux/common/bits/socket.h +index ac5a433..11f6e97 100644 +--- a/libc/sysdeps/linux/common/bits/socket.h ++++ b/libc/sysdeps/linux/common/bits/socket.h +@@ -53,10 +53,20 @@ enum __socket_type + SOCK_SEQPACKET = 5, /* Sequenced, reliable, connection-based, + datagrams of fixed maximum length. */ + #define SOCK_SEQPACKET SOCK_SEQPACKET +- SOCK_PACKET = 10 /* Linux specific way of getting packets ++ SOCK_PACKET = 10, /* Linux specific way of getting packets + at the dev level. For writing rarp and + other similar things on the user level. */ + #define SOCK_PACKET SOCK_PACKET ++ ++ /* Flags to be ORed into the type parameter of socket and socketpair and ++ used for the flags parameter of paccept. */ ++ ++ SOCK_CLOEXEC = 02000000, /* Atomically set close-on-exec flag for the ++ new descriptor(s). */ ++#define SOCK_CLOEXEC SOCK_CLOEXEC ++ SOCK_NONBLOCK = 04000 /* Atomically mark descriptor(s) as ++ non-blocking. */ ++#define SOCK_NONBLOCK SOCK_NONBLOCK + }; + + /* Protocol families. */ +-- +1.7.3.4 + diff --git a/toolchain/uClibc/uClibc-0.9.31.1-fix-error-locale-utf-8.patch b/toolchain/uClibc/uClibc-0.9.31.1-fix-error-locale-utf-8.patch new file mode 100644 index 0000000000..1305add50a --- /dev/null +++ b/toolchain/uClibc/uClibc-0.9.31.1-fix-error-locale-utf-8.patch @@ -0,0 +1,17 @@ +--- + extra/locale/gen_wc8bit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: uClibc-0.9.31/extra/locale/gen_wc8bit.c +=================================================================== +--- uClibc-0.9.31.orig/extra/locale/gen_wc8bit.c ++++ uClibc-0.9.31/extra/locale/gen_wc8bit.c +@@ -120,7 +120,7 @@ + } + + locale_failure: +- printf("could not find a UTF8 locale ... please enable en_US.UTF-8\n"); ++ fprintf(stderr, "could not find a UTF8 locale ... please enable en_US.UTF-8\n"); + return EXIT_FAILURE; + locale_success: + pclose(fp); diff --git a/toolchain/uClibc/uClibc-0.9.31.1-fix-fcntl64-for-64-bit-targets.patch b/toolchain/uClibc/uClibc-0.9.31.1-fix-fcntl64-for-64-bit-targets.patch new file mode 100644 index 0000000000..763bfd39d7 --- /dev/null +++ b/toolchain/uClibc/uClibc-0.9.31.1-fix-fcntl64-for-64-bit-targets.patch @@ -0,0 +1,34 @@ +From 6f1daaaf2d94c1e6184add44eda38b0781b88cf0 Mon Sep 17 00:00:00 2001 +From: Rob Landley +Date: Sun, 16 May 2010 21:41:36 +0000 +Subject: Fix fcntl64 for 64 bit targets. + +64 bit targets often don't have a separate fcntl64() system call, because they don't need one. + +Signed-off-by: Rob Landley +Signed-off-by: Austin Foxley +--- +diff --git a/include/fcntl.h b/include/fcntl.h +index e37073f..3cfb25f 100644 +--- a/include/fcntl.h ++++ b/include/fcntl.h +@@ -73,7 +73,7 @@ __BEGIN_DECLS + + This function is a cancellation point and therefore not marked with + __THROW. */ +-#ifndef __USE_FILE_OFFSET64 ++#if !defined(__USE_FILE_OFFSET64) || defined(__LP64__) + extern int fcntl (int __fd, int __cmd, ...); + libc_hidden_proto(fcntl) + #else +@@ -83,7 +83,7 @@ extern int __REDIRECT (fcntl, (int __fd, int __cmd, ...), fcntl64); + # define fcntl fcntl64 + # endif + #endif +-#ifdef __USE_LARGEFILE64 ++#if defined(__USE_LARGEFILE64) && !defined(__LP64__) + extern int fcntl64 (int __fd, int __cmd, ...); + libc_hidden_proto(fcntl64) + #endif +-- +cgit v0.8.2.1 diff --git a/toolchain/uClibc/uClibc-0.9.31.1-linuxthreads-errno-fix.patch b/toolchain/uClibc/uClibc-0.9.31.1-linuxthreads-errno-fix.patch new file mode 100644 index 0000000000..c49821bde7 --- /dev/null +++ b/toolchain/uClibc/uClibc-0.9.31.1-linuxthreads-errno-fix.patch @@ -0,0 +1,98 @@ +From af8b2d71ce37b9d4d24ddbc755cdea68de02949a Mon Sep 17 00:00:00 2001 +From: Peter Korsgaard +Date: Mon, 5 Jul 2010 14:08:17 +0200 +Subject: [PATCH] don't make __errno_location / __h_errno_location hidden + +Closes #2089 (https://bugs.busybox.net/show_bug.cgi?id=2089) + +__errno_location / __h_errno_location access has to go through the PLT +like malloc/free, so the linuxthread variants gets used instead when +compiling with -pthread. + +Based on http://github.com/mat-c/uClibc/commit/328d392c54aa5dc2b8e7f398a419087de497de2b + +Signed-off-by: Peter Korsgaard +--- + include/netdb.h | 1 - + libc/misc/internals/__errno_location.c | 3 --- + libc/misc/internals/__h_errno_location.c | 1 - + libc/misc/internals/__uClibc_main.c | 2 -- + libc/sysdeps/linux/common/bits/errno.h | 1 - + libc/sysdeps/linux/common/bits/uClibc_errno.h | 3 --- + 6 files changed, 0 insertions(+), 11 deletions(-) + +diff --git a/include/netdb.h b/include/netdb.h +index 9d3807d..ac411ab 100644 +--- a/include/netdb.h ++++ b/include/netdb.h +@@ -59,7 +59,6 @@ __BEGIN_DECLS + + /* Function to get address of global `h_errno' variable. */ + extern int *__h_errno_location (void) __THROW __attribute__ ((__const__)); +-libc_hidden_proto(__h_errno_location) + + /* Macros for accessing h_errno from inside libc. */ + #ifdef _LIBC +diff --git a/libc/misc/internals/__errno_location.c b/libc/misc/internals/__errno_location.c +index 487a9c2..0620860 100644 +--- a/libc/misc/internals/__errno_location.c ++++ b/libc/misc/internals/__errno_location.c +@@ -11,6 +11,3 @@ int * weak_const_function __errno_location (void) + { + return &errno; + } +-#ifdef IS_IN_libc /* not really need, only to keep in sync w/ libc_hidden_proto */ +-libc_hidden_weak(__errno_location) +-#endif +diff --git a/libc/misc/internals/__h_errno_location.c b/libc/misc/internals/__h_errno_location.c +index 213d398..235df4e 100644 +--- a/libc/misc/internals/__h_errno_location.c ++++ b/libc/misc/internals/__h_errno_location.c +@@ -10,4 +10,3 @@ int * weak_const_function __h_errno_location (void) + { + return &h_errno; + } +-libc_hidden_weak(__h_errno_location) +diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c +index 6e520fa..f4a9ebb 100644 +--- a/libc/misc/internals/__uClibc_main.c ++++ b/libc/misc/internals/__uClibc_main.c +@@ -64,9 +64,7 @@ void internal_function _dl_aux_init (ElfW(auxv_t) *av); + * Prototypes. + */ + extern int *weak_const_function __errno_location(void); +-libc_hidden_proto(__errno_location) + extern int *weak_const_function __h_errno_location(void); +-libc_hidden_proto(__h_errno_location) + + extern void weak_function _stdio_init(void) attribute_hidden; + #ifdef __UCLIBC_HAS_LOCALE__ +diff --git a/libc/sysdeps/linux/common/bits/errno.h b/libc/sysdeps/linux/common/bits/errno.h +index 0bf6354..de9688a 100644 +--- a/libc/sysdeps/linux/common/bits/errno.h ++++ b/libc/sysdeps/linux/common/bits/errno.h +@@ -43,7 +43,6 @@ + # ifndef __ASSEMBLER__ + /* Function to get address of global `errno' variable. */ + extern int *__errno_location (void) __THROW __attribute__ ((__const__)); +-libc_hidden_proto(__errno_location) + + # ifdef __UCLIBC_HAS_THREADS__ + /* When using threads, errno is a per-thread value. */ +diff --git a/libc/sysdeps/linux/common/bits/uClibc_errno.h b/libc/sysdeps/linux/common/bits/uClibc_errno.h +index 9c15618..79eb7e6 100644 +--- a/libc/sysdeps/linux/common/bits/uClibc_errno.h ++++ b/libc/sysdeps/linux/common/bits/uClibc_errno.h +@@ -33,9 +33,6 @@ extern int *__errno_location (void) __THROW __attribute__ ((__const__)) + ; + # if defined __UCLIBC_HAS_THREADS__ + # include +-# if defined USE___THREAD && USE___THREAD +-libc_hidden_proto(__errno_location) +-# endif + # endif + + #endif /* !__ASSEMBLER__ */ +-- +1.7.1 + diff --git a/toolchain/uClibc/uClibc-0.9.31.1-more-workarounds-GCC-PR32219.patch b/toolchain/uClibc/uClibc-0.9.31.1-more-workarounds-GCC-PR32219.patch new file mode 100644 index 0000000000..9e6953224c --- /dev/null +++ b/toolchain/uClibc/uClibc-0.9.31.1-more-workarounds-GCC-PR32219.patch @@ -0,0 +1,40 @@ +From aa67771881d65373da448ad5f7a8393f3a1d9469 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= +Date: Wed, 30 Jun 2010 14:46:37 +0300 +Subject: [PATCH] more workarounds for GCC PR32219 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit 2e53dd645d5348f207cec7f8595969dc566c5a55 workarounds GCC +bug when accessing _locale_init and _stdio_init. We need the same +fix for __errno_location and __h_errno_location otherwise we crash +calling null with static and non-threaded builds. + +Signed-off-by: Timo Teräs +Signed-off-by: Bernhard Reutner-Fischer +--- + libc/misc/internals/__uClibc_main.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c +index 3f09ad2..58f6643 100644 +--- a/libc/misc/internals/__uClibc_main.c ++++ b/libc/misc/internals/__uClibc_main.c +@@ -447,11 +447,11 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc, + * have resulted in errno being set nonzero, so set it to 0 before + * we call main. + */ +- if (likely(__errno_location!=NULL)) ++ if (likely(not_null_ptr(__errno_location))) + *(__errno_location()) = 0; + + /* Set h_errno to 0 as well */ +- if (likely(__h_errno_location!=NULL)) ++ if (likely(not_null_ptr(__h_errno_location))) + *(__h_errno_location()) = 0; + + #if defined HAVE_CLEANUP_JMP_BUF && defined __UCLIBC_HAS_THREADS_NATIVE__ +-- +1.7.1 + diff --git a/toolchain/uClibc/uClibc-0.9.31.1-powerpc-ptrace-fix.patch b/toolchain/uClibc/uClibc-0.9.31.1-powerpc-ptrace-fix.patch new file mode 100644 index 0000000000..a5ccecaa3f --- /dev/null +++ b/toolchain/uClibc/uClibc-0.9.31.1-powerpc-ptrace-fix.patch @@ -0,0 +1,62 @@ +[PATCH] powerpc: add PTRACE_EVENT_ defines needed by ltrace + +Equivalent to the common version and kernel headers. + +Signed-off-by: Peter Korsgaard +--- + libc/sysdeps/linux/powerpc/sys/ptrace.h | 41 +++++++++++++++++++++++++++++++- + 1 file changed, 40 insertions(+), 1 deletion(-) + +Index: uClibc-0.9.31/libc/sysdeps/linux/powerpc/sys/ptrace.h +=================================================================== +--- uClibc-0.9.31.orig/libc/sysdeps/linux/powerpc/sys/ptrace.h ++++ uClibc-0.9.31/libc/sysdeps/linux/powerpc/sys/ptrace.h +@@ -79,8 +79,47 @@ enum __ptrace_request + #define PT_DETACH PTRACE_DETACH + + /* Continue and stop at the next (return from) syscall. */ +- PTRACE_SYSCALL = 24 ++ PTRACE_SYSCALL = 24, + #define PT_SYSCALL PTRACE_SYSCALL ++ ++ /* Set ptrace filter options. */ ++ PTRACE_SETOPTIONS = 0x4200, ++#define PT_SETOPTIONS PTRACE_SETOPTIONS ++ ++ /* Get last ptrace message. */ ++ PTRACE_GETEVENTMSG = 0x4201, ++#define PT_GETEVENTMSG PTRACE_GETEVENTMSG ++ ++ /* Get siginfo for process. */ ++ PTRACE_GETSIGINFO = 0x4202, ++#define PT_GETSIGINFO PTRACE_GETSIGINFO ++ ++ /* Set new siginfo for process. */ ++ PTRACE_SETSIGINFO = 0x4203 ++#define PT_SETSIGINFO PTRACE_SETSIGINFO ++}; ++ ++ ++/* Options set using PTRACE_SETOPTIONS. */ ++enum __ptrace_setoptions { ++ PTRACE_O_TRACESYSGOOD = 0x00000001, ++ PTRACE_O_TRACEFORK = 0x00000002, ++ PTRACE_O_TRACEVFORK = 0x00000004, ++ PTRACE_O_TRACECLONE = 0x00000008, ++ PTRACE_O_TRACEEXEC = 0x00000010, ++ PTRACE_O_TRACEVFORKDONE = 0x00000020, ++ PTRACE_O_TRACEEXIT = 0x00000040, ++ PTRACE_O_MASK = 0x0000007f ++}; ++ ++/* Wait extended result codes for the above trace options. */ ++enum __ptrace_eventcodes { ++ PTRACE_EVENT_FORK = 1, ++ PTRACE_EVENT_VFORK = 2, ++ PTRACE_EVENT_CLONE = 3, ++ PTRACE_EVENT_EXEC = 4, ++ PTRACE_EVENT_VFORK_DONE = 5, ++ PTRACE_EVENT_EXIT = 6 + }; + + /* Perform process tracing functions. REQUEST is one of the values diff --git a/toolchain/uClibc/uClibc-0.9.31.1-quad-routines.patch b/toolchain/uClibc/uClibc-0.9.31.1-quad-routines.patch new file mode 100644 index 0000000000..de37c30370 --- /dev/null +++ b/toolchain/uClibc/uClibc-0.9.31.1-quad-routines.patch @@ -0,0 +1,7393 @@ +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/Makefile.arch uClibc-0.9.31/libc/sysdeps/linux/sparc/Makefile.arch +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/Makefile.arch 2010-10-14 14:03:46.000000000 +0200 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/Makefile.arch 2010-10-14 14:36:34.000000000 +0200 +@@ -5,8 +5,15 @@ + # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + # + +-CSRC := brk.c __syscall_error.c qp_ops.c sigaction.c ++CSRC := brk.c __syscall_error.c sigaction.c + + SSRC := \ + __longjmp.S fork.S vfork.S clone.S setjmp.S bsd-setjmp.S bsd-_setjmp.S \ + syscall.S urem.S udiv.S umul.S sdiv.S rem.S pipe.S ++ ++CSRC += $(foreach f, \ ++ q_div.c q_fle.c q_mul.c q_qtoll.c q_stoq.c \ ++ mp_clz_tab.c q_dtoq.c q_flt.c q_neg.c q_qtos.c q_sub.c \ ++ q_add.c q_feq.c q_fne.c q_qtod.c q_qtou.c q_ulltoq.c \ ++ q_cmp.c q_fge.c q_itoq.c q_qtoull.c q_util.c \ ++ q_cmpe.c q_fgt.c q_lltoq.c q_qtoi.c q_sqrt.c q_utoq.c, soft-fp/$(f)) +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/double.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/double.h +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/double.h 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/double.h 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,264 @@ ++/* Software floating-point emulation. ++ Definitions for IEEE Double Precision ++ Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com), ++ Jakub Jelinek (jj@ultra.linux.cz), ++ David S. Miller (davem@redhat.com) and ++ Peter Maydell (pmaydell@chiark.greenend.org.uk). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ In addition to the permissions in the GNU Lesser General Public ++ License, the Free Software Foundation gives you unlimited ++ permission to link the compiled version of this file into ++ combinations with other programs, and to distribute those ++ combinations without any restriction coming from the use of this ++ file. (The Lesser General Public License restrictions do apply in ++ other respects; for example, they cover modification of the file, ++ and distribution when not linked into a combine executable.) ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#if _FP_W_TYPE_SIZE < 32 ++#error "Here's a nickel kid. Go buy yourself a real computer." ++#endif ++ ++#if _FP_W_TYPE_SIZE < 64 ++#define _FP_FRACTBITS_D (2 * _FP_W_TYPE_SIZE) ++#else ++#define _FP_FRACTBITS_D _FP_W_TYPE_SIZE ++#endif ++ ++#define _FP_FRACBITS_D 53 ++#define _FP_FRACXBITS_D (_FP_FRACTBITS_D - _FP_FRACBITS_D) ++#define _FP_WFRACBITS_D (_FP_WORKBITS + _FP_FRACBITS_D) ++#define _FP_WFRACXBITS_D (_FP_FRACTBITS_D - _FP_WFRACBITS_D) ++#define _FP_EXPBITS_D 11 ++#define _FP_EXPBIAS_D 1023 ++#define _FP_EXPMAX_D 2047 ++ ++#define _FP_QNANBIT_D \ ++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE) ++#define _FP_QNANBIT_SH_D \ ++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) ++#define _FP_IMPLBIT_D \ ++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE) ++#define _FP_IMPLBIT_SH_D \ ++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) ++#define _FP_OVERFLOW_D \ ++ ((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE) ++ ++typedef float DFtype __attribute__((mode(DF))); ++ ++#if _FP_W_TYPE_SIZE < 64 ++ ++union _FP_UNION_D ++{ ++ DFtype flt; ++ struct { ++#if __BYTE_ORDER == __BIG_ENDIAN ++ unsigned sign : 1; ++ unsigned exp : _FP_EXPBITS_D; ++ unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; ++ unsigned frac0 : _FP_W_TYPE_SIZE; ++#else ++ unsigned frac0 : _FP_W_TYPE_SIZE; ++ unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; ++ unsigned exp : _FP_EXPBITS_D; ++ unsigned sign : 1; ++#endif ++ } bits __attribute__((packed)); ++}; ++ ++#define FP_DECL_D(X) _FP_DECL(2,X) ++#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val) ++#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_2_P(D,X,val) ++#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_2(D,val,X) ++#define FP_PACK_RAW_DP(val,X) \ ++ do { \ ++ if (!FP_INHIBIT_RESULTS) \ ++ _FP_PACK_RAW_2_P(D,val,X); \ ++ } while (0) ++ ++#define FP_UNPACK_D(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_2(D,X,val); \ ++ _FP_UNPACK_CANONICAL(D,2,X); \ ++ } while (0) ++ ++#define FP_UNPACK_DP(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_2_P(D,X,val); \ ++ _FP_UNPACK_CANONICAL(D,2,X); \ ++ } while (0) ++ ++#define FP_UNPACK_SEMIRAW_D(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_2(D,X,val); \ ++ _FP_UNPACK_SEMIRAW(D,2,X); \ ++ } while (0) ++ ++#define FP_UNPACK_SEMIRAW_DP(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_2_P(D,X,val); \ ++ _FP_UNPACK_SEMIRAW(D,2,X); \ ++ } while (0) ++ ++#define FP_PACK_D(val,X) \ ++ do { \ ++ _FP_PACK_CANONICAL(D,2,X); \ ++ _FP_PACK_RAW_2(D,val,X); \ ++ } while (0) ++ ++#define FP_PACK_DP(val,X) \ ++ do { \ ++ _FP_PACK_CANONICAL(D,2,X); \ ++ if (!FP_INHIBIT_RESULTS) \ ++ _FP_PACK_RAW_2_P(D,val,X); \ ++ } while (0) ++ ++#define FP_PACK_SEMIRAW_D(val,X) \ ++ do { \ ++ _FP_PACK_SEMIRAW(D,2,X); \ ++ _FP_PACK_RAW_2(D,val,X); \ ++ } while (0) ++ ++#define FP_PACK_SEMIRAW_DP(val,X) \ ++ do { \ ++ _FP_PACK_SEMIRAW(D,2,X); \ ++ if (!FP_INHIBIT_RESULTS) \ ++ _FP_PACK_RAW_2_P(D,val,X); \ ++ } while (0) ++ ++#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,2,X) ++#define FP_NEG_D(R,X) _FP_NEG(D,2,R,X) ++#define FP_ADD_D(R,X,Y) _FP_ADD(D,2,R,X,Y) ++#define FP_SUB_D(R,X,Y) _FP_SUB(D,2,R,X,Y) ++#define FP_MUL_D(R,X,Y) _FP_MUL(D,2,R,X,Y) ++#define FP_DIV_D(R,X,Y) _FP_DIV(D,2,R,X,Y) ++#define FP_SQRT_D(R,X) _FP_SQRT(D,2,R,X) ++#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q) ++ ++#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,2,r,X,Y,un) ++#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,2,r,X,Y) ++#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,2,r,X,Y) ++ ++#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,2,r,X,rsz,rsg) ++#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,2,X,r,rs,rt) ++ ++#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_2(X) ++#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_2(X) ++ ++#else ++ ++union _FP_UNION_D ++{ ++ DFtype flt; ++ struct { ++#if __BYTE_ORDER == __BIG_ENDIAN ++ unsigned sign : 1; ++ unsigned exp : _FP_EXPBITS_D; ++ _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); ++#else ++ _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); ++ unsigned exp : _FP_EXPBITS_D; ++ unsigned sign : 1; ++#endif ++ } bits __attribute__((packed)); ++}; ++ ++#define FP_DECL_D(X) _FP_DECL(1,X) ++#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val) ++#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_1_P(D,X,val) ++#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_1(D,val,X) ++#define FP_PACK_RAW_DP(val,X) \ ++ do { \ ++ if (!FP_INHIBIT_RESULTS) \ ++ _FP_PACK_RAW_1_P(D,val,X); \ ++ } while (0) ++ ++#define FP_UNPACK_D(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_1(D,X,val); \ ++ _FP_UNPACK_CANONICAL(D,1,X); \ ++ } while (0) ++ ++#define FP_UNPACK_DP(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_1_P(D,X,val); \ ++ _FP_UNPACK_CANONICAL(D,1,X); \ ++ } while (0) ++ ++#define FP_UNPACK_SEMIRAW_D(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_2(1,X,val); \ ++ _FP_UNPACK_SEMIRAW(D,1,X); \ ++ } while (0) ++ ++#define FP_UNPACK_SEMIRAW_DP(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_2_P(1,X,val); \ ++ _FP_UNPACK_SEMIRAW(D,1,X); \ ++ } while (0) ++ ++#define FP_PACK_D(val,X) \ ++ do { \ ++ _FP_PACK_CANONICAL(D,1,X); \ ++ _FP_PACK_RAW_1(D,val,X); \ ++ } while (0) ++ ++#define FP_PACK_DP(val,X) \ ++ do { \ ++ _FP_PACK_CANONICAL(D,1,X); \ ++ if (!FP_INHIBIT_RESULTS) \ ++ _FP_PACK_RAW_1_P(D,val,X); \ ++ } while (0) ++ ++#define FP_PACK_SEMIRAW_D(val,X) \ ++ do { \ ++ _FP_PACK_SEMIRAW(D,1,X); \ ++ _FP_PACK_RAW_1(D,val,X); \ ++ } while (0) ++ ++#define FP_PACK_SEMIRAW_DP(val,X) \ ++ do { \ ++ _FP_PACK_SEMIRAW(D,1,X); \ ++ if (!FP_INHIBIT_RESULTS) \ ++ _FP_PACK_RAW_1_P(D,val,X); \ ++ } while (0) ++ ++#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,1,X) ++#define FP_NEG_D(R,X) _FP_NEG(D,1,R,X) ++#define FP_ADD_D(R,X,Y) _FP_ADD(D,1,R,X,Y) ++#define FP_SUB_D(R,X,Y) _FP_SUB(D,1,R,X,Y) ++#define FP_MUL_D(R,X,Y) _FP_MUL(D,1,R,X,Y) ++#define FP_DIV_D(R,X,Y) _FP_DIV(D,1,R,X,Y) ++#define FP_SQRT_D(R,X) _FP_SQRT(D,1,R,X) ++#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q) ++ ++/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by ++ the target machine. */ ++ ++#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,1,r,X,Y,un) ++#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y) ++#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,1,r,X,Y) ++ ++#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg) ++#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt) ++ ++#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_1(X) ++#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_1(X) ++ ++#endif /* W_TYPE_SIZE < 64 */ +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/extended.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/extended.h +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/extended.h 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/extended.h 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,431 @@ ++/* Software floating-point emulation. ++ Definitions for IEEE Extended Precision. ++ Copyright (C) 1999,2006,2007 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ In addition to the permissions in the GNU Lesser General Public ++ License, the Free Software Foundation gives you unlimited ++ permission to link the compiled version of this file into ++ combinations with other programs, and to distribute those ++ combinations without any restriction coming from the use of this ++ file. (The Lesser General Public License restrictions do apply in ++ other respects; for example, they cover modification of the file, ++ and distribution when not linked into a combine executable.) ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#if _FP_W_TYPE_SIZE < 32 ++#error "Here's a nickel, kid. Go buy yourself a real computer." ++#endif ++ ++#if _FP_W_TYPE_SIZE < 64 ++#define _FP_FRACTBITS_E (4*_FP_W_TYPE_SIZE) ++#else ++#define _FP_FRACTBITS_E (2*_FP_W_TYPE_SIZE) ++#endif ++ ++#define _FP_FRACBITS_E 64 ++#define _FP_FRACXBITS_E (_FP_FRACTBITS_E - _FP_FRACBITS_E) ++#define _FP_WFRACBITS_E (_FP_WORKBITS + _FP_FRACBITS_E) ++#define _FP_WFRACXBITS_E (_FP_FRACTBITS_E - _FP_WFRACBITS_E) ++#define _FP_EXPBITS_E 15 ++#define _FP_EXPBIAS_E 16383 ++#define _FP_EXPMAX_E 32767 ++ ++#define _FP_QNANBIT_E \ ++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE) ++#define _FP_QNANBIT_SH_E \ ++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) ++#define _FP_IMPLBIT_E \ ++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE) ++#define _FP_IMPLBIT_SH_E \ ++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) ++#define _FP_OVERFLOW_E \ ++ ((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE)) ++ ++typedef float XFtype __attribute__((mode(XF))); ++ ++#if _FP_W_TYPE_SIZE < 64 ++ ++union _FP_UNION_E ++{ ++ XFtype flt; ++ struct ++ { ++#if __BYTE_ORDER == __BIG_ENDIAN ++ unsigned long pad1 : _FP_W_TYPE_SIZE; ++ unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); ++ unsigned long sign : 1; ++ unsigned long exp : _FP_EXPBITS_E; ++ unsigned long frac1 : _FP_W_TYPE_SIZE; ++ unsigned long frac0 : _FP_W_TYPE_SIZE; ++#else ++ unsigned long frac0 : _FP_W_TYPE_SIZE; ++ unsigned long frac1 : _FP_W_TYPE_SIZE; ++ unsigned exp : _FP_EXPBITS_E; ++ unsigned sign : 1; ++#endif /* not bigendian */ ++ } bits __attribute__((packed)); ++}; ++ ++ ++#define FP_DECL_E(X) _FP_DECL(4,X) ++ ++#define FP_UNPACK_RAW_E(X, val) \ ++ do { \ ++ union _FP_UNION_E _flo; _flo.flt = (val); \ ++ \ ++ X##_f[2] = 0; X##_f[3] = 0; \ ++ X##_f[0] = _flo.bits.frac0; \ ++ X##_f[1] = _flo.bits.frac1; \ ++ X##_e = _flo.bits.exp; \ ++ X##_s = _flo.bits.sign; \ ++ } while (0) ++ ++#define FP_UNPACK_RAW_EP(X, val) \ ++ do { \ ++ union _FP_UNION_E *_flo = \ ++ (union _FP_UNION_E *)(val); \ ++ \ ++ X##_f[2] = 0; X##_f[3] = 0; \ ++ X##_f[0] = _flo->bits.frac0; \ ++ X##_f[1] = _flo->bits.frac1; \ ++ X##_e = _flo->bits.exp; \ ++ X##_s = _flo->bits.sign; \ ++ } while (0) ++ ++#define FP_PACK_RAW_E(val, X) \ ++ do { \ ++ union _FP_UNION_E _flo; \ ++ \ ++ if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ ++ else X##_f[1] &= ~(_FP_IMPLBIT_E); \ ++ _flo.bits.frac0 = X##_f[0]; \ ++ _flo.bits.frac1 = X##_f[1]; \ ++ _flo.bits.exp = X##_e; \ ++ _flo.bits.sign = X##_s; \ ++ \ ++ (val) = _flo.flt; \ ++ } while (0) ++ ++#define FP_PACK_RAW_EP(val, X) \ ++ do { \ ++ if (!FP_INHIBIT_RESULTS) \ ++ { \ ++ union _FP_UNION_E *_flo = \ ++ (union _FP_UNION_E *)(val); \ ++ \ ++ if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ ++ else X##_f[1] &= ~(_FP_IMPLBIT_E); \ ++ _flo->bits.frac0 = X##_f[0]; \ ++ _flo->bits.frac1 = X##_f[1]; \ ++ _flo->bits.exp = X##_e; \ ++ _flo->bits.sign = X##_s; \ ++ } \ ++ } while (0) ++ ++#define FP_UNPACK_E(X,val) \ ++ do { \ ++ FP_UNPACK_RAW_E(X,val); \ ++ _FP_UNPACK_CANONICAL(E,4,X); \ ++ } while (0) ++ ++#define FP_UNPACK_EP(X,val) \ ++ do { \ ++ FP_UNPACK_RAW_EP(X,val); \ ++ _FP_UNPACK_CANONICAL(E,4,X); \ ++ } while (0) ++ ++#define FP_UNPACK_SEMIRAW_E(X,val) \ ++ do { \ ++ FP_UNPACK_RAW_E(X,val); \ ++ _FP_UNPACK_SEMIRAW(E,4,X); \ ++ } while (0) ++ ++#define FP_UNPACK_SEMIRAW_EP(X,val) \ ++ do { \ ++ FP_UNPACK_RAW_EP(X,val); \ ++ _FP_UNPACK_SEMIRAW(E,4,X); \ ++ } while (0) ++ ++#define FP_PACK_E(val,X) \ ++ do { \ ++ _FP_PACK_CANONICAL(E,4,X); \ ++ FP_PACK_RAW_E(val,X); \ ++ } while (0) ++ ++#define FP_PACK_EP(val,X) \ ++ do { \ ++ _FP_PACK_CANONICAL(E,4,X); \ ++ FP_PACK_RAW_EP(val,X); \ ++ } while (0) ++ ++#define FP_PACK_SEMIRAW_E(val,X) \ ++ do { \ ++ _FP_PACK_SEMIRAW(E,4,X); \ ++ FP_PACK_RAW_E(val,X); \ ++ } while (0) ++ ++#define FP_PACK_SEMIRAW_EP(val,X) \ ++ do { \ ++ _FP_PACK_SEMIRAW(E,4,X); \ ++ FP_PACK_RAW_EP(val,X); \ ++ } while (0) ++ ++#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,4,X) ++#define FP_NEG_E(R,X) _FP_NEG(E,4,R,X) ++#define FP_ADD_E(R,X,Y) _FP_ADD(E,4,R,X,Y) ++#define FP_SUB_E(R,X,Y) _FP_SUB(E,4,R,X,Y) ++#define FP_MUL_E(R,X,Y) _FP_MUL(E,4,R,X,Y) ++#define FP_DIV_E(R,X,Y) _FP_DIV(E,4,R,X,Y) ++#define FP_SQRT_E(R,X) _FP_SQRT(E,4,R,X) ++ ++/* ++ * Square root algorithms: ++ * We have just one right now, maybe Newton approximation ++ * should be added for those machines where division is fast. ++ * This has special _E version because standard _4 square ++ * root would not work (it has to start normally with the ++ * second word and not the first), but as we have to do it ++ * anyway, we optimize it by doing most of the calculations ++ * in two UWtype registers instead of four. ++ */ ++ ++#define _FP_SQRT_MEAT_E(R, S, T, X, q) \ ++ do { \ ++ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ ++ _FP_FRAC_SRL_4(X, (_FP_WORKBITS)); \ ++ while (q) \ ++ { \ ++ T##_f[1] = S##_f[1] + q; \ ++ if (T##_f[1] <= X##_f[1]) \ ++ { \ ++ S##_f[1] = T##_f[1] + q; \ ++ X##_f[1] -= T##_f[1]; \ ++ R##_f[1] += q; \ ++ } \ ++ _FP_FRAC_SLL_2(X, 1); \ ++ q >>= 1; \ ++ } \ ++ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ ++ while (q) \ ++ { \ ++ T##_f[0] = S##_f[0] + q; \ ++ T##_f[1] = S##_f[1]; \ ++ if (T##_f[1] < X##_f[1] || \ ++ (T##_f[1] == X##_f[1] && \ ++ T##_f[0] <= X##_f[0])) \ ++ { \ ++ S##_f[0] = T##_f[0] + q; \ ++ S##_f[1] += (T##_f[0] > S##_f[0]); \ ++ _FP_FRAC_DEC_2(X, T); \ ++ R##_f[0] += q; \ ++ } \ ++ _FP_FRAC_SLL_2(X, 1); \ ++ q >>= 1; \ ++ } \ ++ _FP_FRAC_SLL_4(R, (_FP_WORKBITS)); \ ++ if (X##_f[0] | X##_f[1]) \ ++ { \ ++ if (S##_f[1] < X##_f[1] || \ ++ (S##_f[1] == X##_f[1] && \ ++ S##_f[0] < X##_f[0])) \ ++ R##_f[0] |= _FP_WORK_ROUND; \ ++ R##_f[0] |= _FP_WORK_STICKY; \ ++ } \ ++ } while (0) ++ ++#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,4,r,X,Y,un) ++#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,4,r,X,Y) ++#define FP_CMP_UNORD_E(r,X,Y) _FP_CMP_UNORD(E,4,r,X,Y) ++ ++#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,4,r,X,rsz,rsg) ++#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,4,X,r,rs,rt) ++ ++#define _FP_FRAC_HIGH_E(X) (X##_f[2]) ++#define _FP_FRAC_HIGH_RAW_E(X) (X##_f[1]) ++ ++#else /* not _FP_W_TYPE_SIZE < 64 */ ++union _FP_UNION_E ++{ ++ XFtype flt; ++ struct { ++#if __BYTE_ORDER == __BIG_ENDIAN ++ _FP_W_TYPE pad : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); ++ unsigned sign : 1; ++ unsigned exp : _FP_EXPBITS_E; ++ _FP_W_TYPE frac : _FP_W_TYPE_SIZE; ++#else ++ _FP_W_TYPE frac : _FP_W_TYPE_SIZE; ++ unsigned exp : _FP_EXPBITS_E; ++ unsigned sign : 1; ++#endif ++ } bits; ++}; ++ ++#define FP_DECL_E(X) _FP_DECL(2,X) ++ ++#define FP_UNPACK_RAW_E(X, val) \ ++ do { \ ++ union _FP_UNION_E _flo; _flo.flt = (val); \ ++ \ ++ X##_f0 = _flo.bits.frac; \ ++ X##_f1 = 0; \ ++ X##_e = _flo.bits.exp; \ ++ X##_s = _flo.bits.sign; \ ++ } while (0) ++ ++#define FP_UNPACK_RAW_EP(X, val) \ ++ do { \ ++ union _FP_UNION_E *_flo = \ ++ (union _FP_UNION_E *)(val); \ ++ \ ++ X##_f0 = _flo->bits.frac; \ ++ X##_f1 = 0; \ ++ X##_e = _flo->bits.exp; \ ++ X##_s = _flo->bits.sign; \ ++ } while (0) ++ ++#define FP_PACK_RAW_E(val, X) \ ++ do { \ ++ union _FP_UNION_E _flo; \ ++ \ ++ if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ ++ else X##_f0 &= ~(_FP_IMPLBIT_E); \ ++ _flo.bits.frac = X##_f0; \ ++ _flo.bits.exp = X##_e; \ ++ _flo.bits.sign = X##_s; \ ++ \ ++ (val) = _flo.flt; \ ++ } while (0) ++ ++#define FP_PACK_RAW_EP(fs, val, X) \ ++ do { \ ++ if (!FP_INHIBIT_RESULTS) \ ++ { \ ++ union _FP_UNION_E *_flo = \ ++ (union _FP_UNION_E *)(val); \ ++ \ ++ if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ ++ else X##_f0 &= ~(_FP_IMPLBIT_E); \ ++ _flo->bits.frac = X##_f0; \ ++ _flo->bits.exp = X##_e; \ ++ _flo->bits.sign = X##_s; \ ++ } \ ++ } while (0) ++ ++ ++#define FP_UNPACK_E(X,val) \ ++ do { \ ++ FP_UNPACK_RAW_E(X,val); \ ++ _FP_UNPACK_CANONICAL(E,2,X); \ ++ } while (0) ++ ++#define FP_UNPACK_EP(X,val) \ ++ do { \ ++ FP_UNPACK_RAW_EP(X,val); \ ++ _FP_UNPACK_CANONICAL(E,2,X); \ ++ } while (0) ++ ++#define FP_UNPACK_SEMIRAW_E(X,val) \ ++ do { \ ++ FP_UNPACK_RAW_E(X,val); \ ++ _FP_UNPACK_SEMIRAW(E,2,X); \ ++ } while (0) ++ ++#define FP_UNPACK_SEMIRAW_EP(X,val) \ ++ do { \ ++ FP_UNPACK_RAW_EP(X,val); \ ++ _FP_UNPACK_SEMIRAW(E,2,X); \ ++ } while (0) ++ ++#define FP_PACK_E(val,X) \ ++ do { \ ++ _FP_PACK_CANONICAL(E,2,X); \ ++ FP_PACK_RAW_E(val,X); \ ++ } while (0) ++ ++#define FP_PACK_EP(val,X) \ ++ do { \ ++ _FP_PACK_CANONICAL(E,2,X); \ ++ FP_PACK_RAW_EP(val,X); \ ++ } while (0) ++ ++#define FP_PACK_SEMIRAW_E(val,X) \ ++ do { \ ++ _FP_PACK_SEMIRAW(E,2,X); \ ++ FP_PACK_RAW_E(val,X); \ ++ } while (0) ++ ++#define FP_PACK_SEMIRAW_EP(val,X) \ ++ do { \ ++ _FP_PACK_SEMIRAW(E,2,X); \ ++ FP_PACK_RAW_EP(val,X); \ ++ } while (0) ++ ++#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,2,X) ++#define FP_NEG_E(R,X) _FP_NEG(E,2,R,X) ++#define FP_ADD_E(R,X,Y) _FP_ADD(E,2,R,X,Y) ++#define FP_SUB_E(R,X,Y) _FP_SUB(E,2,R,X,Y) ++#define FP_MUL_E(R,X,Y) _FP_MUL(E,2,R,X,Y) ++#define FP_DIV_E(R,X,Y) _FP_DIV(E,2,R,X,Y) ++#define FP_SQRT_E(R,X) _FP_SQRT(E,2,R,X) ++ ++/* ++ * Square root algorithms: ++ * We have just one right now, maybe Newton approximation ++ * should be added for those machines where division is fast. ++ * We optimize it by doing most of the calculations ++ * in one UWtype registers instead of two, although we don't ++ * have to. ++ */ ++#define _FP_SQRT_MEAT_E(R, S, T, X, q) \ ++ do { \ ++ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ ++ _FP_FRAC_SRL_2(X, (_FP_WORKBITS)); \ ++ while (q) \ ++ { \ ++ T##_f0 = S##_f0 + q; \ ++ if (T##_f0 <= X##_f0) \ ++ { \ ++ S##_f0 = T##_f0 + q; \ ++ X##_f0 -= T##_f0; \ ++ R##_f0 += q; \ ++ } \ ++ _FP_FRAC_SLL_1(X, 1); \ ++ q >>= 1; \ ++ } \ ++ _FP_FRAC_SLL_2(R, (_FP_WORKBITS)); \ ++ if (X##_f0) \ ++ { \ ++ if (S##_f0 < X##_f0) \ ++ R##_f0 |= _FP_WORK_ROUND; \ ++ R##_f0 |= _FP_WORK_STICKY; \ ++ } \ ++ } while (0) ++ ++#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,2,r,X,Y,un) ++#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,2,r,X,Y) ++#define FP_CMP_UNORD_E(r,X,Y) _FP_CMP_UNORD(E,2,r,X,Y) ++ ++#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,2,r,X,rsz,rsg) ++#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,2,X,r,rs,rt) ++ ++#define _FP_FRAC_HIGH_E(X) (X##_f1) ++#define _FP_FRAC_HIGH_RAW_E(X) (X##_f0) ++ ++#endif /* not _FP_W_TYPE_SIZE < 64 */ +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/longlong.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/longlong.h +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/longlong.h 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/longlong.h 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,1461 @@ ++/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. ++ Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, ++ 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++/* You have to define the following before including this file: ++ ++ UWtype -- An unsigned type, default type for operations (typically a "word") ++ UHWtype -- An unsigned type, at least half the size of UWtype. ++ UDWtype -- An unsigned type, at least twice as large a UWtype ++ W_TYPE_SIZE -- size in bits of UWtype ++ ++ UQItype -- Unsigned 8 bit type. ++ SItype, USItype -- Signed and unsigned 32 bit types. ++ DItype, UDItype -- Signed and unsigned 64 bit types. ++ ++ On a 32 bit machine UWtype should typically be USItype; ++ on a 64 bit machine, UWtype should typically be UDItype. */ ++ ++#define __BITS4 (W_TYPE_SIZE / 4) ++#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) ++#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) ++#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) ++ ++#ifndef W_TYPE_SIZE ++#define W_TYPE_SIZE 32 ++#define UWtype USItype ++#define UHWtype USItype ++#define UDWtype UDItype ++#endif ++ ++extern const UQItype __clz_tab[256] attribute_hidden; ++ ++/* Define auxiliary asm macros. ++ ++ 1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two ++ UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype ++ word product in HIGH_PROD and LOW_PROD. ++ ++ 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a ++ UDWtype product. This is just a variant of umul_ppmm. ++ ++ 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, ++ denominator) divides a UDWtype, composed by the UWtype integers ++ HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient ++ in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less ++ than DENOMINATOR for correct operation. If, in addition, the most ++ significant bit of DENOMINATOR must be 1, then the pre-processor symbol ++ UDIV_NEEDS_NORMALIZATION is defined to 1. ++ ++ 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, ++ denominator). Like udiv_qrnnd but the numbers are signed. The quotient ++ is rounded towards 0. ++ ++ 5) count_leading_zeros(count, x) counts the number of zero-bits from the ++ msb to the first nonzero bit in the UWtype X. This is the number of ++ steps X needs to be shifted left to set the msb. Undefined for X == 0, ++ unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. ++ ++ 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts ++ from the least significant end. ++ ++ 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, ++ high_addend_2, low_addend_2) adds two UWtype integers, composed by ++ HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 ++ respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow ++ (i.e. carry out) is not stored anywhere, and is lost. ++ ++ 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, ++ high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, ++ composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and ++ LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE ++ and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, ++ and is lost. ++ ++ If any of these macros are left undefined for a particular CPU, ++ C macros are used. */ ++ ++/* The CPUs come in alphabetical order below. ++ ++ Please add support for more CPUs here, or improve the current support ++ for the CPUs below! ++ (E.g. WE32100, IBM360.) */ ++ ++#if defined (__GNUC__) && !defined (NO_ASM) ++ ++/* We sometimes need to clobber "cc" with gcc2, but that would not be ++ understood by gcc1. Use cpp to avoid major code duplication. */ ++#if __GNUC__ < 2 ++#define __CLOBBER_CC ++#define __AND_CLOBBER_CC ++#else /* __GNUC__ >= 2 */ ++#define __CLOBBER_CC : "cc" ++#define __AND_CLOBBER_CC , "cc" ++#endif /* __GNUC__ < 2 */ ++ ++#if defined (__alpha) && W_TYPE_SIZE == 64 ++#define umul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ UDItype __m0 = (m0), __m1 = (m1); \ ++ (ph) = __builtin_alpha_umulh (__m0, __m1); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define UMUL_TIME 46 ++#ifndef LONGLONG_STANDALONE ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ do { UDItype __r; \ ++ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ ++ (r) = __r; \ ++ } while (0) ++extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); ++#define UDIV_TIME 220 ++#endif /* LONGLONG_STANDALONE */ ++#ifdef __alpha_cix__ ++#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clzl (X)) ++#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctzl (X)) ++#define COUNT_LEADING_ZEROS_0 64 ++#else ++#define count_leading_zeros(COUNT,X) \ ++ do { \ ++ UDItype __xr = (X), __t, __a; \ ++ __t = __builtin_alpha_cmpbge (0, __xr); \ ++ __a = __clz_tab[__t ^ 0xff] - 1; \ ++ __t = __builtin_alpha_extbl (__xr, __a); \ ++ (COUNT) = 64 - (__clz_tab[__t] + __a*8); \ ++ } while (0) ++#define count_trailing_zeros(COUNT,X) \ ++ do { \ ++ UDItype __xr = (X), __t, __a; \ ++ __t = __builtin_alpha_cmpbge (0, __xr); \ ++ __t = ~__t & -~__t; \ ++ __a = ((__t & 0xCC) != 0) * 2; \ ++ __a += ((__t & 0xF0) != 0) * 4; \ ++ __a += ((__t & 0xAA) != 0); \ ++ __t = __builtin_alpha_extbl (__xr, __a); \ ++ __a <<= 3; \ ++ __t &= -__t; \ ++ __a += ((__t & 0xCC) != 0) * 2; \ ++ __a += ((__t & 0xF0) != 0) * 4; \ ++ __a += ((__t & 0xAA) != 0); \ ++ (COUNT) = __a; \ ++ } while (0) ++#endif /* __alpha_cix__ */ ++#endif /* __alpha */ ++ ++#if defined (__arc__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("add.f %1, %4, %5\n\tadc %0, %2, %3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "%r" ((USItype) (ah)), \ ++ "rIJ" ((USItype) (bh)), \ ++ "%r" ((USItype) (al)), \ ++ "rIJ" ((USItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("sub.f %1, %4, %5\n\tsbc %0, %2, %3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "r" ((USItype) (ah)), \ ++ "rIJ" ((USItype) (bh)), \ ++ "r" ((USItype) (al)), \ ++ "rIJ" ((USItype) (bl))) ++/* Call libgcc routine. */ ++#define umul_ppmm(w1, w0, u, v) \ ++do { \ ++ DWunion __w; \ ++ __w.ll = __umulsidi3 (u, v); \ ++ w1 = __w.s.high; \ ++ w0 = __w.s.low; \ ++} while (0) ++#define __umulsidi3 __umulsidi3 ++UDItype __umulsidi3 (USItype, USItype); ++#endif ++ ++#if defined (__arm__) && !defined (__thumb__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("adds %1, %4, %5\n\tadc %0, %2, %3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "%r" ((USItype) (ah)), \ ++ "rI" ((USItype) (bh)), \ ++ "%r" ((USItype) (al)), \ ++ "rI" ((USItype) (bl)) __CLOBBER_CC) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subs %1, %4, %5\n\tsbc %0, %2, %3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "r" ((USItype) (ah)), \ ++ "rI" ((USItype) (bh)), \ ++ "r" ((USItype) (al)), \ ++ "rI" ((USItype) (bl)) __CLOBBER_CC) ++#define umul_ppmm(xh, xl, a, b) \ ++{register USItype __t0, __t1, __t2; \ ++ __asm__ ("%@ Inlined umul_ppmm\n" \ ++ " mov %2, %5, lsr #16\n" \ ++ " mov %0, %6, lsr #16\n" \ ++ " bic %3, %5, %2, lsl #16\n" \ ++ " bic %4, %6, %0, lsl #16\n" \ ++ " mul %1, %3, %4\n" \ ++ " mul %4, %2, %4\n" \ ++ " mul %3, %0, %3\n" \ ++ " mul %0, %2, %0\n" \ ++ " adds %3, %4, %3\n" \ ++ " addcs %0, %0, #65536\n" \ ++ " adds %1, %1, %3, lsl #16\n" \ ++ " adc %0, %0, %3, lsr #16" \ ++ : "=&r" ((USItype) (xh)), \ ++ "=r" ((USItype) (xl)), \ ++ "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ ++ : "r" ((USItype) (a)), \ ++ "r" ((USItype) (b)) __CLOBBER_CC );} ++#define UMUL_TIME 20 ++#define UDIV_TIME 100 ++#endif /* __arm__ */ ++ ++#if defined(__arm__) ++/* Let gcc decide how best to implement count_leading_zeros. */ ++#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) ++#define COUNT_LEADING_ZEROS_0 32 ++#endif ++ ++#if defined (__CRIS__) && __CRIS_arch_version >= 3 ++#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) ++#if __CRIS_arch_version >= 8 ++#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) ++#endif ++#endif /* __CRIS__ */ ++ ++#if defined (__hppa) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "%rM" ((USItype) (ah)), \ ++ "rM" ((USItype) (bh)), \ ++ "%rM" ((USItype) (al)), \ ++ "rM" ((USItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("sub %4,%5,%1\n\tsubb %2,%3,%0" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "rM" ((USItype) (ah)), \ ++ "rM" ((USItype) (bh)), \ ++ "rM" ((USItype) (al)), \ ++ "rM" ((USItype) (bl))) ++#if defined (_PA_RISC1_1) ++#define umul_ppmm(w1, w0, u, v) \ ++ do { \ ++ union \ ++ { \ ++ UDItype __f; \ ++ struct {USItype __w1, __w0;} __w1w0; \ ++ } __t; \ ++ __asm__ ("xmpyu %1,%2,%0" \ ++ : "=x" (__t.__f) \ ++ : "x" ((USItype) (u)), \ ++ "x" ((USItype) (v))); \ ++ (w1) = __t.__w1w0.__w1; \ ++ (w0) = __t.__w1w0.__w0; \ ++ } while (0) ++#define UMUL_TIME 8 ++#else ++#define UMUL_TIME 30 ++#endif ++#define UDIV_TIME 40 ++#define count_leading_zeros(count, x) \ ++ do { \ ++ USItype __tmp; \ ++ __asm__ ( \ ++ "ldi 1,%0\n" \ ++" extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \ ++" extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n"\ ++" ldo 16(%0),%0 ; Yes. Perform add.\n" \ ++" extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \ ++" extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n"\ ++" ldo 8(%0),%0 ; Yes. Perform add.\n" \ ++" extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \ ++" extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n"\ ++" ldo 4(%0),%0 ; Yes. Perform add.\n" \ ++" extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \ ++" extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n"\ ++" ldo 2(%0),%0 ; Yes. Perform add.\n" \ ++" extru %1,30,1,%1 ; Extract bit 1.\n" \ ++" sub %0,%1,%0 ; Subtract it.\n" \ ++ : "=r" (count), "=r" (__tmp) : "1" (x)); \ ++ } while (0) ++#endif ++ ++#if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32 ++#define smul_ppmm(xh, xl, m0, m1) \ ++ do { \ ++ union {DItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __x; \ ++ __asm__ ("lr %N0,%1\n\tmr %0,%2" \ ++ : "=&r" (__x.__ll) \ ++ : "r" (m0), "r" (m1)); \ ++ (xh) = __x.__i.__h; (xl) = __x.__i.__l; \ ++ } while (0) ++#define sdiv_qrnnd(q, r, n1, n0, d) \ ++ do { \ ++ union {DItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __x; \ ++ __x.__i.__h = n1; __x.__i.__l = n0; \ ++ __asm__ ("dr %0,%2" \ ++ : "=r" (__x.__ll) \ ++ : "0" (__x.__ll), "r" (d)); \ ++ (q) = __x.__i.__l; (r) = __x.__i.__h; \ ++ } while (0) ++#endif ++ ++#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("add{l} {%5,%1|%1,%5}\n\tadc{l} {%3,%0|%0,%3}" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "%0" ((USItype) (ah)), \ ++ "g" ((USItype) (bh)), \ ++ "%1" ((USItype) (al)), \ ++ "g" ((USItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("sub{l} {%5,%1|%1,%5}\n\tsbb{l} {%3,%0|%0,%3}" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "0" ((USItype) (ah)), \ ++ "g" ((USItype) (bh)), \ ++ "1" ((USItype) (al)), \ ++ "g" ((USItype) (bl))) ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("mul{l} %3" \ ++ : "=a" ((USItype) (w0)), \ ++ "=d" ((USItype) (w1)) \ ++ : "%0" ((USItype) (u)), \ ++ "rm" ((USItype) (v))) ++#define udiv_qrnnd(q, r, n1, n0, dv) \ ++ __asm__ ("div{l} %4" \ ++ : "=a" ((USItype) (q)), \ ++ "=d" ((USItype) (r)) \ ++ : "0" ((USItype) (n0)), \ ++ "1" ((USItype) (n1)), \ ++ "rm" ((USItype) (dv))) ++#define count_leading_zeros(count, x) ((count) = __builtin_clz (x)) ++#define count_trailing_zeros(count, x) ((count) = __builtin_ctz (x)) ++#define UMUL_TIME 40 ++#define UDIV_TIME 40 ++#endif /* 80x86 */ ++ ++#if (defined (__x86_64__) || defined (__i386__)) && W_TYPE_SIZE == 64 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("add{q} {%5,%1|%1,%5}\n\tadc{q} {%3,%0|%0,%3}" \ ++ : "=r" ((UDItype) (sh)), \ ++ "=&r" ((UDItype) (sl)) \ ++ : "%0" ((UDItype) (ah)), \ ++ "rme" ((UDItype) (bh)), \ ++ "%1" ((UDItype) (al)), \ ++ "rme" ((UDItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("sub{q} {%5,%1|%1,%5}\n\tsbb{q} {%3,%0|%0,%3}" \ ++ : "=r" ((UDItype) (sh)), \ ++ "=&r" ((UDItype) (sl)) \ ++ : "0" ((UDItype) (ah)), \ ++ "rme" ((UDItype) (bh)), \ ++ "1" ((UDItype) (al)), \ ++ "rme" ((UDItype) (bl))) ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("mul{q} %3" \ ++ : "=a" ((UDItype) (w0)), \ ++ "=d" ((UDItype) (w1)) \ ++ : "%0" ((UDItype) (u)), \ ++ "rm" ((UDItype) (v))) ++#define udiv_qrnnd(q, r, n1, n0, dv) \ ++ __asm__ ("div{q} %4" \ ++ : "=a" ((UDItype) (q)), \ ++ "=d" ((UDItype) (r)) \ ++ : "0" ((UDItype) (n0)), \ ++ "1" ((UDItype) (n1)), \ ++ "rm" ((UDItype) (dv))) ++#define count_leading_zeros(count, x) ((count) = __builtin_clzl (x)) ++#define count_trailing_zeros(count, x) ((count) = __builtin_ctzl (x)) ++#define UMUL_TIME 40 ++#define UDIV_TIME 40 ++#endif /* x86_64 */ ++ ++#if defined (__i960__) && W_TYPE_SIZE == 32 ++#define umul_ppmm(w1, w0, u, v) \ ++ ({union {UDItype __ll; \ ++ struct {USItype __l, __h;} __i; \ ++ } __xx; \ ++ __asm__ ("emul %2,%1,%0" \ ++ : "=d" (__xx.__ll) \ ++ : "%dI" ((USItype) (u)), \ ++ "dI" ((USItype) (v))); \ ++ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) ++#define __umulsidi3(u, v) \ ++ ({UDItype __w; \ ++ __asm__ ("emul %2,%1,%0" \ ++ : "=d" (__w) \ ++ : "%dI" ((USItype) (u)), \ ++ "dI" ((USItype) (v))); \ ++ __w; }) ++#endif /* __i960__ */ ++ ++#if defined (__M32R__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ /* The cmp clears the condition bit. */ \ ++ __asm__ ("cmp %0,%0\n\taddx %1,%5\n\taddx %0,%3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "0" ((USItype) (ah)), \ ++ "r" ((USItype) (bh)), \ ++ "1" ((USItype) (al)), \ ++ "r" ((USItype) (bl)) \ ++ : "cbit") ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ /* The cmp clears the condition bit. */ \ ++ __asm__ ("cmp %0,%0\n\tsubx %1,%5\n\tsubx %0,%3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "0" ((USItype) (ah)), \ ++ "r" ((USItype) (bh)), \ ++ "1" ((USItype) (al)), \ ++ "r" ((USItype) (bl)) \ ++ : "cbit") ++#endif /* __M32R__ */ ++ ++#if defined (__mc68000__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \ ++ : "=d" ((USItype) (sh)), \ ++ "=&d" ((USItype) (sl)) \ ++ : "%0" ((USItype) (ah)), \ ++ "d" ((USItype) (bh)), \ ++ "%1" ((USItype) (al)), \ ++ "g" ((USItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \ ++ : "=d" ((USItype) (sh)), \ ++ "=&d" ((USItype) (sl)) \ ++ : "0" ((USItype) (ah)), \ ++ "d" ((USItype) (bh)), \ ++ "1" ((USItype) (al)), \ ++ "g" ((USItype) (bl))) ++ ++/* The '020, '030, '040, '060 and CPU32 have 32x32->64 and 64/32->32q-32r. */ ++#if (defined (__mc68020__) && !defined (__mc68060__)) ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("mulu%.l %3,%1:%0" \ ++ : "=d" ((USItype) (w0)), \ ++ "=d" ((USItype) (w1)) \ ++ : "%0" ((USItype) (u)), \ ++ "dmi" ((USItype) (v))) ++#define UMUL_TIME 45 ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ __asm__ ("divu%.l %4,%1:%0" \ ++ : "=d" ((USItype) (q)), \ ++ "=d" ((USItype) (r)) \ ++ : "0" ((USItype) (n0)), \ ++ "1" ((USItype) (n1)), \ ++ "dmi" ((USItype) (d))) ++#define UDIV_TIME 90 ++#define sdiv_qrnnd(q, r, n1, n0, d) \ ++ __asm__ ("divs%.l %4,%1:%0" \ ++ : "=d" ((USItype) (q)), \ ++ "=d" ((USItype) (r)) \ ++ : "0" ((USItype) (n0)), \ ++ "1" ((USItype) (n1)), \ ++ "dmi" ((USItype) (d))) ++ ++#elif defined (__mcoldfire__) /* not mc68020 */ ++ ++#define umul_ppmm(xh, xl, a, b) \ ++ __asm__ ("| Inlined umul_ppmm\n" \ ++ " move%.l %2,%/d0\n" \ ++ " move%.l %3,%/d1\n" \ ++ " move%.l %/d0,%/d2\n" \ ++ " swap %/d0\n" \ ++ " move%.l %/d1,%/d3\n" \ ++ " swap %/d1\n" \ ++ " move%.w %/d2,%/d4\n" \ ++ " mulu %/d3,%/d4\n" \ ++ " mulu %/d1,%/d2\n" \ ++ " mulu %/d0,%/d3\n" \ ++ " mulu %/d0,%/d1\n" \ ++ " move%.l %/d4,%/d0\n" \ ++ " clr%.w %/d0\n" \ ++ " swap %/d0\n" \ ++ " add%.l %/d0,%/d2\n" \ ++ " add%.l %/d3,%/d2\n" \ ++ " jcc 1f\n" \ ++ " add%.l %#65536,%/d1\n" \ ++ "1: swap %/d2\n" \ ++ " moveq %#0,%/d0\n" \ ++ " move%.w %/d2,%/d0\n" \ ++ " move%.w %/d4,%/d2\n" \ ++ " move%.l %/d2,%1\n" \ ++ " add%.l %/d1,%/d0\n" \ ++ " move%.l %/d0,%0" \ ++ : "=g" ((USItype) (xh)), \ ++ "=g" ((USItype) (xl)) \ ++ : "g" ((USItype) (a)), \ ++ "g" ((USItype) (b)) \ ++ : "d0", "d1", "d2", "d3", "d4") ++#define UMUL_TIME 100 ++#define UDIV_TIME 400 ++#else /* not ColdFire */ ++/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX. */ ++#define umul_ppmm(xh, xl, a, b) \ ++ __asm__ ("| Inlined umul_ppmm\n" \ ++ " move%.l %2,%/d0\n" \ ++ " move%.l %3,%/d1\n" \ ++ " move%.l %/d0,%/d2\n" \ ++ " swap %/d0\n" \ ++ " move%.l %/d1,%/d3\n" \ ++ " swap %/d1\n" \ ++ " move%.w %/d2,%/d4\n" \ ++ " mulu %/d3,%/d4\n" \ ++ " mulu %/d1,%/d2\n" \ ++ " mulu %/d0,%/d3\n" \ ++ " mulu %/d0,%/d1\n" \ ++ " move%.l %/d4,%/d0\n" \ ++ " eor%.w %/d0,%/d0\n" \ ++ " swap %/d0\n" \ ++ " add%.l %/d0,%/d2\n" \ ++ " add%.l %/d3,%/d2\n" \ ++ " jcc 1f\n" \ ++ " add%.l %#65536,%/d1\n" \ ++ "1: swap %/d2\n" \ ++ " moveq %#0,%/d0\n" \ ++ " move%.w %/d2,%/d0\n" \ ++ " move%.w %/d4,%/d2\n" \ ++ " move%.l %/d2,%1\n" \ ++ " add%.l %/d1,%/d0\n" \ ++ " move%.l %/d0,%0" \ ++ : "=g" ((USItype) (xh)), \ ++ "=g" ((USItype) (xl)) \ ++ : "g" ((USItype) (a)), \ ++ "g" ((USItype) (b)) \ ++ : "d0", "d1", "d2", "d3", "d4") ++#define UMUL_TIME 100 ++#define UDIV_TIME 400 ++ ++#endif /* not mc68020 */ ++ ++/* The '020, '030, '040 and '060 have bitfield insns. ++ cpu32 disguises as a 68020, but lacks them. */ ++#if defined (__mc68020__) && !defined (__mcpu32__) ++#define count_leading_zeros(count, x) \ ++ __asm__ ("bfffo %1{%b2:%b2},%0" \ ++ : "=d" ((USItype) (count)) \ ++ : "od" ((USItype) (x)), "n" (0)) ++/* Some ColdFire architectures have a ff1 instruction supported via ++ __builtin_clz. */ ++#elif defined (__mcfisaaplus__) || defined (__mcfisac__) ++#define count_leading_zeros(count,x) ((count) = __builtin_clz (x)) ++#define COUNT_LEADING_ZEROS_0 32 ++#endif ++#endif /* mc68000 */ ++ ++#if defined (__m88000__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "%rJ" ((USItype) (ah)), \ ++ "rJ" ((USItype) (bh)), \ ++ "%rJ" ((USItype) (al)), \ ++ "rJ" ((USItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "rJ" ((USItype) (ah)), \ ++ "rJ" ((USItype) (bh)), \ ++ "rJ" ((USItype) (al)), \ ++ "rJ" ((USItype) (bl))) ++#define count_leading_zeros(count, x) \ ++ do { \ ++ USItype __cbtmp; \ ++ __asm__ ("ff1 %0,%1" \ ++ : "=r" (__cbtmp) \ ++ : "r" ((USItype) (x))); \ ++ (count) = __cbtmp ^ 31; \ ++ } while (0) ++#define COUNT_LEADING_ZEROS_0 63 /* sic */ ++#if defined (__mc88110__) ++#define umul_ppmm(wh, wl, u, v) \ ++ do { \ ++ union {UDItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __xx; \ ++ __asm__ ("mulu.d %0,%1,%2" \ ++ : "=r" (__xx.__ll) \ ++ : "r" ((USItype) (u)), \ ++ "r" ((USItype) (v))); \ ++ (wh) = __xx.__i.__h; \ ++ (wl) = __xx.__i.__l; \ ++ } while (0) ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ ({union {UDItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __xx; \ ++ USItype __q; \ ++ __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ ++ __asm__ ("divu.d %0,%1,%2" \ ++ : "=r" (__q) \ ++ : "r" (__xx.__ll), \ ++ "r" ((USItype) (d))); \ ++ (r) = (n0) - __q * (d); (q) = __q; }) ++#define UMUL_TIME 5 ++#define UDIV_TIME 25 ++#else ++#define UMUL_TIME 17 ++#define UDIV_TIME 150 ++#endif /* __mc88110__ */ ++#endif /* __m88000__ */ ++ ++#if defined (__mips__) && W_TYPE_SIZE == 32 ++#define umul_ppmm(w1, w0, u, v) \ ++ do { \ ++ UDItype __x = (UDItype) (USItype) (u) * (USItype) (v); \ ++ (w1) = (USItype) (__x >> 32); \ ++ (w0) = (USItype) (__x); \ ++ } while (0) ++#define UMUL_TIME 10 ++#define UDIV_TIME 100 ++ ++#if (__mips == 32 || __mips == 64) && ! __mips16 ++#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) ++#define COUNT_LEADING_ZEROS_0 32 ++#endif ++#endif /* __mips__ */ ++ ++#if defined (__ns32000__) && W_TYPE_SIZE == 32 ++#define umul_ppmm(w1, w0, u, v) \ ++ ({union {UDItype __ll; \ ++ struct {USItype __l, __h;} __i; \ ++ } __xx; \ ++ __asm__ ("meid %2,%0" \ ++ : "=g" (__xx.__ll) \ ++ : "%0" ((USItype) (u)), \ ++ "g" ((USItype) (v))); \ ++ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) ++#define __umulsidi3(u, v) \ ++ ({UDItype __w; \ ++ __asm__ ("meid %2,%0" \ ++ : "=g" (__w) \ ++ : "%0" ((USItype) (u)), \ ++ "g" ((USItype) (v))); \ ++ __w; }) ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ ({union {UDItype __ll; \ ++ struct {USItype __l, __h;} __i; \ ++ } __xx; \ ++ __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ ++ __asm__ ("deid %2,%0" \ ++ : "=g" (__xx.__ll) \ ++ : "0" (__xx.__ll), \ ++ "g" ((USItype) (d))); \ ++ (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) ++#define count_trailing_zeros(count,x) \ ++ do { \ ++ __asm__ ("ffsd %2,%0" \ ++ : "=r" ((USItype) (count)) \ ++ : "0" ((USItype) 0), \ ++ "r" ((USItype) (x))); \ ++ } while (0) ++#endif /* __ns32000__ */ ++ ++/* FIXME: We should test _IBMR2 here when we add assembly support for the ++ system vendor compilers. ++ FIXME: What's needed for gcc PowerPC VxWorks? __vxworks__ is not good ++ enough, since that hits ARM and m68k too. */ ++#if (defined (_ARCH_PPC) /* AIX */ \ ++ || defined (_ARCH_PWR) /* AIX */ \ ++ || defined (_ARCH_COM) /* AIX */ \ ++ || defined (__powerpc__) /* gcc */ \ ++ || defined (__POWERPC__) /* BEOS */ \ ++ || defined (__ppc__) /* Darwin */ \ ++ || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */ \ ++ || (defined (PPC) && defined (CPU_FAMILY) /* VxWorks */ \ ++ && CPU_FAMILY == PPC) \ ++ ) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ if (__builtin_constant_p (bh) && (bh) == 0) \ ++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ ++ else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ ++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ ++ else \ ++ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ ++ : "=r" (sh), "=&r" (sl) \ ++ : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ ++ } while (0) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ if (__builtin_constant_p (ah) && (ah) == 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ ++ else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ ++ else if (__builtin_constant_p (bh) && (bh) == 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ ++ else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ ++ else \ ++ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ ++ : "=r" (sh), "=&r" (sl) \ ++ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ ++ } while (0) ++#define count_leading_zeros(count, x) \ ++ __asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x)) ++#define COUNT_LEADING_ZEROS_0 32 ++#if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \ ++ || defined (__ppc__) \ ++ || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */ \ ++ || (defined (PPC) && defined (CPU_FAMILY) /* VxWorks */ \ ++ && CPU_FAMILY == PPC) ++#define umul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ USItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define UMUL_TIME 15 ++#define smul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ SItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define SMUL_TIME 14 ++#define UDIV_TIME 120 ++#elif defined (_ARCH_PWR) ++#define UMUL_TIME 8 ++#define smul_ppmm(xh, xl, m0, m1) \ ++ __asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1)) ++#define SMUL_TIME 4 ++#define sdiv_qrnnd(q, r, nh, nl, d) \ ++ __asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d)) ++#define UDIV_TIME 100 ++#endif ++#endif /* 32-bit POWER architecture variants. */ ++ ++/* We should test _IBMR2 here when we add assembly support for the system ++ vendor compilers. */ ++#if (defined (_ARCH_PPC64) || defined (__powerpc64__)) && W_TYPE_SIZE == 64 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ if (__builtin_constant_p (bh) && (bh) == 0) \ ++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ ++ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ ++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ ++ else \ ++ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ ++ : "=r" (sh), "=&r" (sl) \ ++ : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ ++ } while (0) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ if (__builtin_constant_p (ah) && (ah) == 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ ++ else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ ++ else if (__builtin_constant_p (bh) && (bh) == 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ ++ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ ++ else \ ++ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ ++ : "=r" (sh), "=&r" (sl) \ ++ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ ++ } while (0) ++#define count_leading_zeros(count, x) \ ++ __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x)) ++#define COUNT_LEADING_ZEROS_0 64 ++#define umul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ UDItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define UMUL_TIME 15 ++#define smul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ DItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define SMUL_TIME 14 /* ??? */ ++#define UDIV_TIME 120 /* ??? */ ++#endif /* 64-bit PowerPC. */ ++ ++#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("a %1,%5\n\tae %0,%3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "%0" ((USItype) (ah)), \ ++ "r" ((USItype) (bh)), \ ++ "%1" ((USItype) (al)), \ ++ "r" ((USItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("s %1,%5\n\tse %0,%3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "0" ((USItype) (ah)), \ ++ "r" ((USItype) (bh)), \ ++ "1" ((USItype) (al)), \ ++ "r" ((USItype) (bl))) ++#define umul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ USItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ( \ ++ "s r2,r2\n" \ ++" mts r10,%2\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" cas %0,r2,r0\n" \ ++" mfs r10,%1" \ ++ : "=r" ((USItype) (ph)), \ ++ "=r" ((USItype) (pl)) \ ++ : "%r" (__m0), \ ++ "r" (__m1) \ ++ : "r2"); \ ++ (ph) += ((((SItype) __m0 >> 31) & __m1) \ ++ + (((SItype) __m1 >> 31) & __m0)); \ ++ } while (0) ++#define UMUL_TIME 20 ++#define UDIV_TIME 200 ++#define count_leading_zeros(count, x) \ ++ do { \ ++ if ((x) >= 0x10000) \ ++ __asm__ ("clz %0,%1" \ ++ : "=r" ((USItype) (count)) \ ++ : "r" ((USItype) (x) >> 16)); \ ++ else \ ++ { \ ++ __asm__ ("clz %0,%1" \ ++ : "=r" ((USItype) (count)) \ ++ : "r" ((USItype) (x))); \ ++ (count) += 16; \ ++ } \ ++ } while (0) ++#endif ++ ++#if defined(__sh__) && !__SHMEDIA__ && W_TYPE_SIZE == 32 ++#ifndef __sh1__ ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ( \ ++ "dmulu.l %2,%3\n\tsts%M1 macl,%1\n\tsts%M0 mach,%0" \ ++ : "=r<" ((USItype)(w1)), \ ++ "=r<" ((USItype)(w0)) \ ++ : "r" ((USItype)(u)), \ ++ "r" ((USItype)(v)) \ ++ : "macl", "mach") ++#define UMUL_TIME 5 ++#endif ++ ++/* This is the same algorithm as __udiv_qrnnd_c. */ ++#define UDIV_NEEDS_NORMALIZATION 1 ++ ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ do { \ ++ extern UWtype __udiv_qrnnd_16 (UWtype, UWtype) \ ++ __attribute__ ((visibility ("hidden"))); \ ++ /* r0: rn r1: qn */ /* r0: n1 r4: n0 r5: d r6: d1 */ /* r2: __m */ \ ++ __asm__ ( \ ++ "mov%M4 %4,r5\n" \ ++" swap.w %3,r4\n" \ ++" swap.w r5,r6\n" \ ++" jsr @%5\n" \ ++" shll16 r6\n" \ ++" swap.w r4,r4\n" \ ++" jsr @%5\n" \ ++" swap.w r1,%0\n" \ ++" or r1,%0" \ ++ : "=r" (q), "=&z" (r) \ ++ : "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16) \ ++ : "r1", "r2", "r4", "r5", "r6", "pr"); \ ++ } while (0) ++ ++#define UDIV_TIME 80 ++ ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("clrt;subc %5,%1; subc %4,%0" \ ++ : "=r" (sh), "=r" (sl) \ ++ : "0" (ah), "1" (al), "r" (bh), "r" (bl)) ++ ++#endif /* __sh__ */ ++ ++#if defined (__SH5__) && __SHMEDIA__ && W_TYPE_SIZE == 32 ++#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v) ++#define count_leading_zeros(count, x) \ ++ do \ ++ { \ ++ UDItype x_ = (USItype)(x); \ ++ SItype c_; \ ++ \ ++ __asm__ ("nsb %1, %0" : "=r" (c_) : "r" (x_)); \ ++ (count) = c_ - 31; \ ++ } \ ++ while (0) ++#define COUNT_LEADING_ZEROS_0 32 ++#endif ++ ++#if defined (__sparc__) && !defined (__arch64__) && !defined (__sparcv9) \ ++ && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "%rJ" ((USItype) (ah)), \ ++ "rI" ((USItype) (bh)), \ ++ "%rJ" ((USItype) (al)), \ ++ "rI" ((USItype) (bl)) \ ++ __CLOBBER_CC) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "rJ" ((USItype) (ah)), \ ++ "rI" ((USItype) (bh)), \ ++ "rJ" ((USItype) (al)), \ ++ "rI" ((USItype) (bl)) \ ++ __CLOBBER_CC) ++#if defined (__sparc_v8__) ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ ++ : "=r" ((USItype) (w1)), \ ++ "=r" ((USItype) (w0)) \ ++ : "r" ((USItype) (u)), \ ++ "r" ((USItype) (v))) ++#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ ++ __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\ ++ : "=&r" ((USItype) (__q)), \ ++ "=&r" ((USItype) (__r)) \ ++ : "r" ((USItype) (__n1)), \ ++ "r" ((USItype) (__n0)), \ ++ "r" ((USItype) (__d))) ++#else ++#if defined (__sparclite__) ++/* This has hardware multiply but not divide. It also has two additional ++ instructions scan (ffs from high bit) and divscc. */ ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ ++ : "=r" ((USItype) (w1)), \ ++ "=r" ((USItype) (w0)) \ ++ : "r" ((USItype) (u)), \ ++ "r" ((USItype) (v))) ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ __asm__ ("! Inlined udiv_qrnnd\n" \ ++" wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \ ++" tst %%g0\n" \ ++" divscc %3,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%0\n" \ ++" rd %%y,%1\n" \ ++" bl,a 1f\n" \ ++" add %1,%4,%1\n" \ ++"1: ! End of inline udiv_qrnnd" \ ++ : "=r" ((USItype) (q)), \ ++ "=r" ((USItype) (r)) \ ++ : "r" ((USItype) (n1)), \ ++ "r" ((USItype) (n0)), \ ++ "rI" ((USItype) (d)) \ ++ : "g1" __AND_CLOBBER_CC) ++#define UDIV_TIME 37 ++#define count_leading_zeros(count, x) \ ++ do { \ ++ __asm__ ("scan %1,1,%0" \ ++ : "=r" ((USItype) (count)) \ ++ : "r" ((USItype) (x))); \ ++ } while (0) ++/* Early sparclites return 63 for an argument of 0, but they warn that future ++ implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 ++ undefined. */ ++#else ++/* SPARC without integer multiplication and divide instructions. ++ (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */ ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("! Inlined umul_ppmm\n" \ ++" wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n"\ ++" sra %3,31,%%o5 ! Don't move this insn\n" \ ++" and %2,%%o5,%%o5 ! Don't move this insn\n" \ ++" andcc %%g0,0,%%g1 ! Don't move this insn\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,0,%%g1\n" \ ++" add %%g1,%%o5,%0\n" \ ++" rd %%y,%1" \ ++ : "=r" ((USItype) (w1)), \ ++ "=r" ((USItype) (w0)) \ ++ : "%rI" ((USItype) (u)), \ ++ "r" ((USItype) (v)) \ ++ : "g1", "o5" __AND_CLOBBER_CC) ++#define UMUL_TIME 39 /* 39 instructions */ ++/* It's quite necessary to add this much assembler for the sparc. ++ The default udiv_qrnnd (in C) is more than 10 times slower! */ ++#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ ++ __asm__ ("! Inlined udiv_qrnnd\n" \ ++" mov 32,%%g1\n" \ ++" subcc %1,%2,%%g0\n" \ ++"1: bcs 5f\n" \ ++" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ ++" sub %1,%2,%1 ! this kills msb of n\n" \ ++" addx %1,%1,%1 ! so this can't give carry\n" \ ++" subcc %%g1,1,%%g1\n" \ ++"2: bne 1b\n" \ ++" subcc %1,%2,%%g0\n" \ ++" bcs 3f\n" \ ++" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ ++" b 3f\n" \ ++" sub %1,%2,%1 ! this kills msb of n\n" \ ++"4: sub %1,%2,%1\n" \ ++"5: addxcc %1,%1,%1\n" \ ++" bcc 2b\n" \ ++" subcc %%g1,1,%%g1\n" \ ++"! Got carry from n. Subtract next step to cancel this carry.\n" \ ++" bne 4b\n" \ ++" addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n" \ ++" sub %1,%2,%1\n" \ ++"3: xnor %0,0,%0\n" \ ++" ! End of inline udiv_qrnnd" \ ++ : "=&r" ((USItype) (__q)), \ ++ "=&r" ((USItype) (__r)) \ ++ : "r" ((USItype) (__d)), \ ++ "1" ((USItype) (__n1)), \ ++ "0" ((USItype) (__n0)) : "g1" __AND_CLOBBER_CC) ++#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ ++#endif /* __sparclite__ */ ++#endif /* __sparc_v8__ */ ++#endif /* sparc32 */ ++ ++#if ((defined (__sparc__) && defined (__arch64__)) || defined (__sparcv9)) \ ++ && W_TYPE_SIZE == 64 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("addcc %r4,%5,%1\n\t" \ ++ "add %r2,%3,%0\n\t" \ ++ "bcs,a,pn %%xcc, 1f\n\t" \ ++ "add %0, 1, %0\n" \ ++ "1:" \ ++ : "=r" ((UDItype)(sh)), \ ++ "=&r" ((UDItype)(sl)) \ ++ : "%rJ" ((UDItype)(ah)), \ ++ "rI" ((UDItype)(bh)), \ ++ "%rJ" ((UDItype)(al)), \ ++ "rI" ((UDItype)(bl)) \ ++ __CLOBBER_CC) ++ ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subcc %r4,%5,%1\n\t" \ ++ "sub %r2,%3,%0\n\t" \ ++ "bcs,a,pn %%xcc, 1f\n\t" \ ++ "sub %0, 1, %0\n\t" \ ++ "1:" \ ++ : "=r" ((UDItype)(sh)), \ ++ "=&r" ((UDItype)(sl)) \ ++ : "rJ" ((UDItype)(ah)), \ ++ "rI" ((UDItype)(bh)), \ ++ "rJ" ((UDItype)(al)), \ ++ "rI" ((UDItype)(bl)) \ ++ __CLOBBER_CC) ++ ++#define umul_ppmm(wh, wl, u, v) \ ++ do { \ ++ UDItype tmp1, tmp2, tmp3, tmp4; \ ++ __asm__ __volatile__ ( \ ++ "srl %7,0,%3\n\t" \ ++ "mulx %3,%6,%1\n\t" \ ++ "srlx %6,32,%2\n\t" \ ++ "mulx %2,%3,%4\n\t" \ ++ "sllx %4,32,%5\n\t" \ ++ "srl %6,0,%3\n\t" \ ++ "sub %1,%5,%5\n\t" \ ++ "srlx %5,32,%5\n\t" \ ++ "addcc %4,%5,%4\n\t" \ ++ "srlx %7,32,%5\n\t" \ ++ "mulx %3,%5,%3\n\t" \ ++ "mulx %2,%5,%5\n\t" \ ++ "sethi %%hi(0x80000000),%2\n\t" \ ++ "addcc %4,%3,%4\n\t" \ ++ "srlx %4,32,%4\n\t" \ ++ "add %2,%2,%2\n\t" \ ++ "movcc %%xcc,%%g0,%2\n\t" \ ++ "addcc %5,%4,%5\n\t" \ ++ "sllx %3,32,%3\n\t" \ ++ "add %1,%3,%1\n\t" \ ++ "add %5,%2,%0" \ ++ : "=r" ((UDItype)(wh)), \ ++ "=&r" ((UDItype)(wl)), \ ++ "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \ ++ : "r" ((UDItype)(u)), \ ++ "r" ((UDItype)(v)) \ ++ __CLOBBER_CC); \ ++ } while (0) ++#define UMUL_TIME 96 ++#define UDIV_TIME 230 ++#endif /* sparc64 */ ++ ++#if defined (__vax__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("addl2 %5,%1\n\tadwc %3,%0" \ ++ : "=g" ((USItype) (sh)), \ ++ "=&g" ((USItype) (sl)) \ ++ : "%0" ((USItype) (ah)), \ ++ "g" ((USItype) (bh)), \ ++ "%1" ((USItype) (al)), \ ++ "g" ((USItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subl2 %5,%1\n\tsbwc %3,%0" \ ++ : "=g" ((USItype) (sh)), \ ++ "=&g" ((USItype) (sl)) \ ++ : "0" ((USItype) (ah)), \ ++ "g" ((USItype) (bh)), \ ++ "1" ((USItype) (al)), \ ++ "g" ((USItype) (bl))) ++#define umul_ppmm(xh, xl, m0, m1) \ ++ do { \ ++ union { \ ++ UDItype __ll; \ ++ struct {USItype __l, __h;} __i; \ ++ } __xx; \ ++ USItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("emul %1,%2,$0,%0" \ ++ : "=r" (__xx.__ll) \ ++ : "g" (__m0), \ ++ "g" (__m1)); \ ++ (xh) = __xx.__i.__h; \ ++ (xl) = __xx.__i.__l; \ ++ (xh) += ((((SItype) __m0 >> 31) & __m1) \ ++ + (((SItype) __m1 >> 31) & __m0)); \ ++ } while (0) ++#define sdiv_qrnnd(q, r, n1, n0, d) \ ++ do { \ ++ union {DItype __ll; \ ++ struct {SItype __l, __h;} __i; \ ++ } __xx; \ ++ __xx.__i.__h = n1; __xx.__i.__l = n0; \ ++ __asm__ ("ediv %3,%2,%0,%1" \ ++ : "=g" (q), "=g" (r) \ ++ : "g" (__xx.__ll), "g" (d)); \ ++ } while (0) ++#endif /* __vax__ */ ++ ++#if defined (__xtensa__) && W_TYPE_SIZE == 32 ++/* This code is not Xtensa-configuration-specific, so rely on the compiler ++ to expand builtin functions depending on what configuration features ++ are available. This avoids library calls when the operation can be ++ performed in-line. */ ++#define umul_ppmm(w1, w0, u, v) \ ++ do { \ ++ DWunion __w; \ ++ __w.ll = __builtin_umulsidi3 (u, v); \ ++ w1 = __w.s.high; \ ++ w0 = __w.s.low; \ ++ } while (0) ++#define __umulsidi3(u, v) __builtin_umulsidi3 (u, v) ++#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) ++#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) ++#endif /* __xtensa__ */ ++ ++#if defined (__z8000__) && W_TYPE_SIZE == 16 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ ++ : "=r" ((unsigned int)(sh)), \ ++ "=&r" ((unsigned int)(sl)) \ ++ : "%0" ((unsigned int)(ah)), \ ++ "r" ((unsigned int)(bh)), \ ++ "%1" ((unsigned int)(al)), \ ++ "rQR" ((unsigned int)(bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ ++ : "=r" ((unsigned int)(sh)), \ ++ "=&r" ((unsigned int)(sl)) \ ++ : "0" ((unsigned int)(ah)), \ ++ "r" ((unsigned int)(bh)), \ ++ "1" ((unsigned int)(al)), \ ++ "rQR" ((unsigned int)(bl))) ++#define umul_ppmm(xh, xl, m0, m1) \ ++ do { \ ++ union {long int __ll; \ ++ struct {unsigned int __h, __l;} __i; \ ++ } __xx; \ ++ unsigned int __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mult %S0,%H3" \ ++ : "=r" (__xx.__i.__h), \ ++ "=r" (__xx.__i.__l) \ ++ : "%1" (__m0), \ ++ "rQR" (__m1)); \ ++ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ ++ (xh) += ((((signed int) __m0 >> 15) & __m1) \ ++ + (((signed int) __m1 >> 15) & __m0)); \ ++ } while (0) ++#endif /* __z8000__ */ ++ ++#endif /* __GNUC__ */ ++ ++/* If this machine has no inline assembler, use C macros. */ ++ ++#if !defined (add_ssaaaa) ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ UWtype __x; \ ++ __x = (al) + (bl); \ ++ (sh) = (ah) + (bh) + (__x < (al)); \ ++ (sl) = __x; \ ++ } while (0) ++#endif ++ ++#if !defined (sub_ddmmss) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ UWtype __x; \ ++ __x = (al) - (bl); \ ++ (sh) = (ah) - (bh) - (__x > (al)); \ ++ (sl) = __x; \ ++ } while (0) ++#endif ++ ++/* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of ++ smul_ppmm. */ ++#if !defined (umul_ppmm) && defined (smul_ppmm) ++#define umul_ppmm(w1, w0, u, v) \ ++ do { \ ++ UWtype __w1; \ ++ UWtype __xm0 = (u), __xm1 = (v); \ ++ smul_ppmm (__w1, w0, __xm0, __xm1); \ ++ (w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1) \ ++ + (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0); \ ++ } while (0) ++#endif ++ ++/* If we still don't have umul_ppmm, define it using plain C. */ ++#if !defined (umul_ppmm) ++#define umul_ppmm(w1, w0, u, v) \ ++ do { \ ++ UWtype __x0, __x1, __x2, __x3; \ ++ UHWtype __ul, __vl, __uh, __vh; \ ++ \ ++ __ul = __ll_lowpart (u); \ ++ __uh = __ll_highpart (u); \ ++ __vl = __ll_lowpart (v); \ ++ __vh = __ll_highpart (v); \ ++ \ ++ __x0 = (UWtype) __ul * __vl; \ ++ __x1 = (UWtype) __ul * __vh; \ ++ __x2 = (UWtype) __uh * __vl; \ ++ __x3 = (UWtype) __uh * __vh; \ ++ \ ++ __x1 += __ll_highpart (__x0);/* this can't give carry */ \ ++ __x1 += __x2; /* but this indeed can */ \ ++ if (__x1 < __x2) /* did we get it? */ \ ++ __x3 += __ll_B; /* yes, add it in the proper pos. */ \ ++ \ ++ (w1) = __x3 + __ll_highpart (__x1); \ ++ (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ ++ } while (0) ++#endif ++ ++#if !defined (__umulsidi3) ++#define __umulsidi3(u, v) \ ++ ({DWunion __w; \ ++ umul_ppmm (__w.s.high, __w.s.low, u, v); \ ++ __w.ll; }) ++#endif ++ ++/* Define this unconditionally, so it can be used for debugging. */ ++#define __udiv_qrnnd_c(q, r, n1, n0, d) \ ++ do { \ ++ UWtype __d1, __d0, __q1, __q0; \ ++ UWtype __r1, __r0, __m; \ ++ __d1 = __ll_highpart (d); \ ++ __d0 = __ll_lowpart (d); \ ++ \ ++ __r1 = (n1) % __d1; \ ++ __q1 = (n1) / __d1; \ ++ __m = (UWtype) __q1 * __d0; \ ++ __r1 = __r1 * __ll_B | __ll_highpart (n0); \ ++ if (__r1 < __m) \ ++ { \ ++ __q1--, __r1 += (d); \ ++ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ ++ if (__r1 < __m) \ ++ __q1--, __r1 += (d); \ ++ } \ ++ __r1 -= __m; \ ++ \ ++ __r0 = __r1 % __d1; \ ++ __q0 = __r1 / __d1; \ ++ __m = (UWtype) __q0 * __d0; \ ++ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ ++ if (__r0 < __m) \ ++ { \ ++ __q0--, __r0 += (d); \ ++ if (__r0 >= (d)) \ ++ if (__r0 < __m) \ ++ __q0--, __r0 += (d); \ ++ } \ ++ __r0 -= __m; \ ++ \ ++ (q) = (UWtype) __q1 * __ll_B | __q0; \ ++ (r) = __r0; \ ++ } while (0) ++ ++/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through ++ __udiv_w_sdiv (defined in libgcc or elsewhere). */ ++#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) ++#define udiv_qrnnd(q, r, nh, nl, d) \ ++ do { \ ++ USItype __r; \ ++ (q) = __udiv_w_sdiv (&__r, nh, nl, d); \ ++ (r) = __r; \ ++ } while (0) ++#endif ++ ++/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ ++#if !defined (udiv_qrnnd) ++#define UDIV_NEEDS_NORMALIZATION 1 ++#define udiv_qrnnd __udiv_qrnnd_c ++#endif ++ ++#if !defined (count_leading_zeros) ++#define count_leading_zeros(count, x) \ ++ do { \ ++ UWtype __xr = (x); \ ++ UWtype __a; \ ++ \ ++ if (W_TYPE_SIZE <= 32) \ ++ { \ ++ __a = __xr < ((UWtype)1<<2*__BITS4) \ ++ ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \ ++ : (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ ++ } \ ++ else \ ++ { \ ++ for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ ++ if (((__xr >> __a) & 0xff) != 0) \ ++ break; \ ++ } \ ++ \ ++ (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ ++ } while (0) ++#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE ++#endif ++ ++#if !defined (count_trailing_zeros) ++/* Define count_trailing_zeros using count_leading_zeros. The latter might be ++ defined in asm, but if it is not, the C version above is good enough. */ ++#define count_trailing_zeros(count, x) \ ++ do { \ ++ UWtype __ctz_x = (x); \ ++ UWtype __ctz_c; \ ++ count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ ++ (count) = W_TYPE_SIZE - 1 - __ctz_c; \ ++ } while (0) ++#endif ++ ++#ifndef UDIV_NEEDS_NORMALIZATION ++#define UDIV_NEEDS_NORMALIZATION 0 ++#endif +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/mp_clz_tab.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/mp_clz_tab.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/mp_clz_tab.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/mp_clz_tab.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,37 @@ ++/* __clz_tab -- support for longlong.h ++ Copyright (C) 1991, 1993, 1994, 1997 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. Its master source is NOT part of ++ the C library, however. The master source lives in the GNU MP Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#if 0 ++#include ++#include "gmp-impl.h" ++#endif ++ ++const ++unsigned char __clz_tab[] = ++{ ++ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, ++ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, ++ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, ++ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, ++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ++}; +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-1.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-1.h +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-1.h 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-1.h 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,302 @@ ++/* Software floating-point emulation. ++ Basic one-word fraction declaration and manipulation. ++ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com), ++ Jakub Jelinek (jj@ultra.linux.cz), ++ David S. Miller (davem@redhat.com) and ++ Peter Maydell (pmaydell@chiark.greenend.org.uk). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ In addition to the permissions in the GNU Lesser General Public ++ License, the Free Software Foundation gives you unlimited ++ permission to link the compiled version of this file into ++ combinations with other programs, and to distribute those ++ combinations without any restriction coming from the use of this ++ file. (The Lesser General Public License restrictions do apply in ++ other respects; for example, they cover modification of the file, ++ and distribution when not linked into a combine executable.) ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#define _FP_FRAC_DECL_1(X) _FP_W_TYPE X##_f ++#define _FP_FRAC_COPY_1(D,S) (D##_f = S##_f) ++#define _FP_FRAC_SET_1(X,I) (X##_f = I) ++#define _FP_FRAC_HIGH_1(X) (X##_f) ++#define _FP_FRAC_LOW_1(X) (X##_f) ++#define _FP_FRAC_WORD_1(X,w) (X##_f) ++ ++#define _FP_FRAC_ADDI_1(X,I) (X##_f += I) ++#define _FP_FRAC_SLL_1(X,N) \ ++ do { \ ++ if (__builtin_constant_p(N) && (N) == 1) \ ++ X##_f += X##_f; \ ++ else \ ++ X##_f <<= (N); \ ++ } while (0) ++#define _FP_FRAC_SRL_1(X,N) (X##_f >>= N) ++ ++/* Right shift with sticky-lsb. */ ++#define _FP_FRAC_SRST_1(X,S,N,sz) __FP_FRAC_SRST_1(X##_f, S, N, sz) ++#define _FP_FRAC_SRS_1(X,N,sz) __FP_FRAC_SRS_1(X##_f, N, sz) ++ ++#define __FP_FRAC_SRST_1(X,S,N,sz) \ ++do { \ ++ S = (__builtin_constant_p(N) && (N) == 1 \ ++ ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0); \ ++ X = X >> (N); \ ++} while (0) ++ ++#define __FP_FRAC_SRS_1(X,N,sz) \ ++ (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1 \ ++ ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0))) ++ ++#define _FP_FRAC_ADD_1(R,X,Y) (R##_f = X##_f + Y##_f) ++#define _FP_FRAC_SUB_1(R,X,Y) (R##_f = X##_f - Y##_f) ++#define _FP_FRAC_DEC_1(X,Y) (X##_f -= Y##_f) ++#define _FP_FRAC_CLZ_1(z, X) __FP_CLZ(z, X##_f) ++ ++/* Predicates */ ++#define _FP_FRAC_NEGP_1(X) ((_FP_WS_TYPE)X##_f < 0) ++#define _FP_FRAC_ZEROP_1(X) (X##_f == 0) ++#define _FP_FRAC_OVERP_1(fs,X) (X##_f & _FP_OVERFLOW_##fs) ++#define _FP_FRAC_CLEAR_OVERP_1(fs,X) (X##_f &= ~_FP_OVERFLOW_##fs) ++#define _FP_FRAC_EQ_1(X, Y) (X##_f == Y##_f) ++#define _FP_FRAC_GE_1(X, Y) (X##_f >= Y##_f) ++#define _FP_FRAC_GT_1(X, Y) (X##_f > Y##_f) ++ ++#define _FP_ZEROFRAC_1 0 ++#define _FP_MINFRAC_1 1 ++#define _FP_MAXFRAC_1 (~(_FP_WS_TYPE)0) ++ ++/* ++ * Unpack the raw bits of a native fp value. Do not classify or ++ * normalize the data. ++ */ ++ ++#define _FP_UNPACK_RAW_1(fs, X, val) \ ++ do { \ ++ union _FP_UNION_##fs _flo; _flo.flt = (val); \ ++ \ ++ X##_f = _flo.bits.frac; \ ++ X##_e = _flo.bits.exp; \ ++ X##_s = _flo.bits.sign; \ ++ } while (0) ++ ++#define _FP_UNPACK_RAW_1_P(fs, X, val) \ ++ do { \ ++ union _FP_UNION_##fs *_flo = \ ++ (union _FP_UNION_##fs *)(val); \ ++ \ ++ X##_f = _flo->bits.frac; \ ++ X##_e = _flo->bits.exp; \ ++ X##_s = _flo->bits.sign; \ ++ } while (0) ++ ++/* ++ * Repack the raw bits of a native fp value. ++ */ ++ ++#define _FP_PACK_RAW_1(fs, val, X) \ ++ do { \ ++ union _FP_UNION_##fs _flo; \ ++ \ ++ _flo.bits.frac = X##_f; \ ++ _flo.bits.exp = X##_e; \ ++ _flo.bits.sign = X##_s; \ ++ \ ++ (val) = _flo.flt; \ ++ } while (0) ++ ++#define _FP_PACK_RAW_1_P(fs, val, X) \ ++ do { \ ++ union _FP_UNION_##fs *_flo = \ ++ (union _FP_UNION_##fs *)(val); \ ++ \ ++ _flo->bits.frac = X##_f; \ ++ _flo->bits.exp = X##_e; \ ++ _flo->bits.sign = X##_s; \ ++ } while (0) ++ ++ ++/* ++ * Multiplication algorithms: ++ */ ++ ++/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the ++ multiplication immediately. */ ++ ++#define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y) \ ++ do { \ ++ R##_f = X##_f * Y##_f; \ ++ /* Normalize since we know where the msb of the multiplicands \ ++ were (bit B), we know that the msb of the of the product is \ ++ at either 2B or 2B-1. */ \ ++ _FP_FRAC_SRS_1(R, wfracbits-1, 2*wfracbits); \ ++ } while (0) ++ ++/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ ++ ++#define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit) \ ++ do { \ ++ _FP_W_TYPE _Z_f0, _Z_f1; \ ++ doit(_Z_f1, _Z_f0, X##_f, Y##_f); \ ++ /* Normalize since we know where the msb of the multiplicands \ ++ were (bit B), we know that the msb of the of the product is \ ++ at either 2B or 2B-1. */ \ ++ _FP_FRAC_SRS_2(_Z, wfracbits-1, 2*wfracbits); \ ++ R##_f = _Z_f0; \ ++ } while (0) ++ ++/* Finally, a simple widening multiply algorithm. What fun! */ ++ ++#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y) \ ++ do { \ ++ _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1; \ ++ \ ++ /* split the words in half */ \ ++ _xh = X##_f >> (_FP_W_TYPE_SIZE/2); \ ++ _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ ++ _yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \ ++ _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ ++ \ ++ /* multiply the pieces */ \ ++ _z_f0 = _xl * _yl; \ ++ _a_f0 = _xh * _yl; \ ++ _a_f1 = _xl * _yh; \ ++ _z_f1 = _xh * _yh; \ ++ \ ++ /* reassemble into two full words */ \ ++ if ((_a_f0 += _a_f1) < _a_f1) \ ++ _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2); \ ++ _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2); \ ++ _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2); \ ++ _FP_FRAC_ADD_2(_z, _z, _a); \ ++ \ ++ /* normalize */ \ ++ _FP_FRAC_SRS_2(_z, wfracbits - 1, 2*wfracbits); \ ++ R##_f = _z_f0; \ ++ } while (0) ++ ++ ++/* ++ * Division algorithms: ++ */ ++ ++/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the ++ division immediately. Give this macro either _FP_DIV_HELP_imm for ++ C primitives or _FP_DIV_HELP_ldiv for the ISO function. Which you ++ choose will depend on what the compiler does with divrem4. */ ++ ++#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \ ++ do { \ ++ _FP_W_TYPE _q, _r; \ ++ X##_f <<= (X##_f < Y##_f \ ++ ? R##_e--, _FP_WFRACBITS_##fs \ ++ : _FP_WFRACBITS_##fs - 1); \ ++ doit(_q, _r, X##_f, Y##_f); \ ++ R##_f = _q | (_r != 0); \ ++ } while (0) ++ ++/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd ++ that may be useful in this situation. This first is for a primitive ++ that requires normalization, the second for one that does not. Look ++ for UDIV_NEEDS_NORMALIZATION to tell which your machine needs. */ ++ ++#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y) \ ++ do { \ ++ _FP_W_TYPE _nh, _nl, _q, _r, _y; \ ++ \ ++ /* Normalize Y -- i.e. make the most significant bit set. */ \ ++ _y = Y##_f << _FP_WFRACXBITS_##fs; \ ++ \ ++ /* Shift X op correspondingly high, that is, up one full word. */ \ ++ if (X##_f < Y##_f) \ ++ { \ ++ R##_e--; \ ++ _nl = 0; \ ++ _nh = X##_f; \ ++ } \ ++ else \ ++ { \ ++ _nl = X##_f << (_FP_W_TYPE_SIZE - 1); \ ++ _nh = X##_f >> 1; \ ++ } \ ++ \ ++ udiv_qrnnd(_q, _r, _nh, _nl, _y); \ ++ R##_f = _q | (_r != 0); \ ++ } while (0) ++ ++#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y) \ ++ do { \ ++ _FP_W_TYPE _nh, _nl, _q, _r; \ ++ if (X##_f < Y##_f) \ ++ { \ ++ R##_e--; \ ++ _nl = X##_f << _FP_WFRACBITS_##fs; \ ++ _nh = X##_f >> _FP_WFRACXBITS_##fs; \ ++ } \ ++ else \ ++ { \ ++ _nl = X##_f << (_FP_WFRACBITS_##fs - 1); \ ++ _nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \ ++ } \ ++ udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \ ++ R##_f = _q | (_r != 0); \ ++ } while (0) ++ ++ ++/* ++ * Square root algorithms: ++ * We have just one right now, maybe Newton approximation ++ * should be added for those machines where division is fast. ++ */ ++ ++#define _FP_SQRT_MEAT_1(R, S, T, X, q) \ ++ do { \ ++ while (q != _FP_WORK_ROUND) \ ++ { \ ++ T##_f = S##_f + q; \ ++ if (T##_f <= X##_f) \ ++ { \ ++ S##_f = T##_f + q; \ ++ X##_f -= T##_f; \ ++ R##_f += q; \ ++ } \ ++ _FP_FRAC_SLL_1(X, 1); \ ++ q >>= 1; \ ++ } \ ++ if (X##_f) \ ++ { \ ++ if (S##_f < X##_f) \ ++ R##_f |= _FP_WORK_ROUND; \ ++ R##_f |= _FP_WORK_STICKY; \ ++ } \ ++ } while (0) ++ ++/* ++ * Assembly/disassembly for converting to/from integral types. ++ * No shifting or overflow handled here. ++ */ ++ ++#define _FP_FRAC_ASSEMBLE_1(r, X, rsize) (r = X##_f) ++#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize) (X##_f = r) ++ ++ ++/* ++ * Convert FP values between word sizes ++ */ ++ ++#define _FP_FRAC_COPY_1_1(D, S) (D##_f = S##_f) +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-2.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-2.h +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-2.h 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-2.h 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,617 @@ ++/* Software floating-point emulation. ++ Basic two-word fraction declaration and manipulation. ++ Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com), ++ Jakub Jelinek (jj@ultra.linux.cz), ++ David S. Miller (davem@redhat.com) and ++ Peter Maydell (pmaydell@chiark.greenend.org.uk). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ In addition to the permissions in the GNU Lesser General Public ++ License, the Free Software Foundation gives you unlimited ++ permission to link the compiled version of this file into ++ combinations with other programs, and to distribute those ++ combinations without any restriction coming from the use of this ++ file. (The Lesser General Public License restrictions do apply in ++ other respects; for example, they cover modification of the file, ++ and distribution when not linked into a combine executable.) ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#define _FP_FRAC_DECL_2(X) _FP_W_TYPE X##_f0, X##_f1 ++#define _FP_FRAC_COPY_2(D,S) (D##_f0 = S##_f0, D##_f1 = S##_f1) ++#define _FP_FRAC_SET_2(X,I) __FP_FRAC_SET_2(X, I) ++#define _FP_FRAC_HIGH_2(X) (X##_f1) ++#define _FP_FRAC_LOW_2(X) (X##_f0) ++#define _FP_FRAC_WORD_2(X,w) (X##_f##w) ++ ++#define _FP_FRAC_SLL_2(X,N) \ ++(void)(((N) < _FP_W_TYPE_SIZE) \ ++ ? ({ \ ++ if (__builtin_constant_p(N) && (N) == 1) \ ++ { \ ++ X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0); \ ++ X##_f0 += X##_f0; \ ++ } \ ++ else \ ++ { \ ++ X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \ ++ X##_f0 <<= (N); \ ++ } \ ++ 0; \ ++ }) \ ++ : ({ \ ++ X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE); \ ++ X##_f0 = 0; \ ++ })) ++ ++ ++#define _FP_FRAC_SRL_2(X,N) \ ++(void)(((N) < _FP_W_TYPE_SIZE) \ ++ ? ({ \ ++ X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \ ++ X##_f1 >>= (N); \ ++ }) \ ++ : ({ \ ++ X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE); \ ++ X##_f1 = 0; \ ++ })) ++ ++/* Right shift with sticky-lsb. */ ++#define _FP_FRAC_SRST_2(X,S, N,sz) \ ++(void)(((N) < _FP_W_TYPE_SIZE) \ ++ ? ({ \ ++ S = (__builtin_constant_p(N) && (N) == 1 \ ++ ? X##_f0 & 1 \ ++ : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0); \ ++ X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N)); \ ++ X##_f1 >>= (N); \ ++ }) \ ++ : ({ \ ++ S = ((((N) == _FP_W_TYPE_SIZE \ ++ ? 0 \ ++ : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ ++ | X##_f0) != 0); \ ++ X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE)); \ ++ X##_f1 = 0; \ ++ })) ++ ++#define _FP_FRAC_SRS_2(X,N,sz) \ ++(void)(((N) < _FP_W_TYPE_SIZE) \ ++ ? ({ \ ++ X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) | \ ++ (__builtin_constant_p(N) && (N) == 1 \ ++ ? X##_f0 & 1 \ ++ : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0)); \ ++ X##_f1 >>= (N); \ ++ }) \ ++ : ({ \ ++ X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) | \ ++ ((((N) == _FP_W_TYPE_SIZE \ ++ ? 0 \ ++ : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ ++ | X##_f0) != 0)); \ ++ X##_f1 = 0; \ ++ })) ++ ++#define _FP_FRAC_ADDI_2(X,I) \ ++ __FP_FRAC_ADDI_2(X##_f1, X##_f0, I) ++ ++#define _FP_FRAC_ADD_2(R,X,Y) \ ++ __FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0) ++ ++#define _FP_FRAC_SUB_2(R,X,Y) \ ++ __FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0) ++ ++#define _FP_FRAC_DEC_2(X,Y) \ ++ __FP_FRAC_DEC_2(X##_f1, X##_f0, Y##_f1, Y##_f0) ++ ++#define _FP_FRAC_CLZ_2(R,X) \ ++ do { \ ++ if (X##_f1) \ ++ __FP_CLZ(R,X##_f1); \ ++ else \ ++ { \ ++ __FP_CLZ(R,X##_f0); \ ++ R += _FP_W_TYPE_SIZE; \ ++ } \ ++ } while(0) ++ ++/* Predicates */ ++#define _FP_FRAC_NEGP_2(X) ((_FP_WS_TYPE)X##_f1 < 0) ++#define _FP_FRAC_ZEROP_2(X) ((X##_f1 | X##_f0) == 0) ++#define _FP_FRAC_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs) ++#define _FP_FRAC_CLEAR_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs) ++#define _FP_FRAC_EQ_2(X, Y) (X##_f1 == Y##_f1 && X##_f0 == Y##_f0) ++#define _FP_FRAC_GT_2(X, Y) \ ++ (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0)) ++#define _FP_FRAC_GE_2(X, Y) \ ++ (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0)) ++ ++#define _FP_ZEROFRAC_2 0, 0 ++#define _FP_MINFRAC_2 0, 1 ++#define _FP_MAXFRAC_2 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0) ++ ++/* ++ * Internals ++ */ ++ ++#define __FP_FRAC_SET_2(X,I1,I0) (X##_f0 = I0, X##_f1 = I1) ++ ++#define __FP_CLZ_2(R, xh, xl) \ ++ do { \ ++ if (xh) \ ++ __FP_CLZ(R,xh); \ ++ else \ ++ { \ ++ __FP_CLZ(R,xl); \ ++ R += _FP_W_TYPE_SIZE; \ ++ } \ ++ } while(0) ++ ++#if 0 ++ ++#ifndef __FP_FRAC_ADDI_2 ++#define __FP_FRAC_ADDI_2(xh, xl, i) \ ++ (xh += ((xl += i) < i)) ++#endif ++#ifndef __FP_FRAC_ADD_2 ++#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \ ++ (rh = xh + yh + ((rl = xl + yl) < xl)) ++#endif ++#ifndef __FP_FRAC_SUB_2 ++#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \ ++ (rh = xh - yh - ((rl = xl - yl) > xl)) ++#endif ++#ifndef __FP_FRAC_DEC_2 ++#define __FP_FRAC_DEC_2(xh, xl, yh, yl) \ ++ do { \ ++ UWtype _t = xl; \ ++ xh -= yh + ((xl -= yl) > _t); \ ++ } while (0) ++#endif ++ ++#else ++ ++#undef __FP_FRAC_ADDI_2 ++#define __FP_FRAC_ADDI_2(xh, xl, i) add_ssaaaa(xh, xl, xh, xl, 0, i) ++#undef __FP_FRAC_ADD_2 ++#define __FP_FRAC_ADD_2 add_ssaaaa ++#undef __FP_FRAC_SUB_2 ++#define __FP_FRAC_SUB_2 sub_ddmmss ++#undef __FP_FRAC_DEC_2 ++#define __FP_FRAC_DEC_2(xh, xl, yh, yl) sub_ddmmss(xh, xl, xh, xl, yh, yl) ++ ++#endif ++ ++/* ++ * Unpack the raw bits of a native fp value. Do not classify or ++ * normalize the data. ++ */ ++ ++#define _FP_UNPACK_RAW_2(fs, X, val) \ ++ do { \ ++ union _FP_UNION_##fs _flo; _flo.flt = (val); \ ++ \ ++ X##_f0 = _flo.bits.frac0; \ ++ X##_f1 = _flo.bits.frac1; \ ++ X##_e = _flo.bits.exp; \ ++ X##_s = _flo.bits.sign; \ ++ } while (0) ++ ++#define _FP_UNPACK_RAW_2_P(fs, X, val) \ ++ do { \ ++ union _FP_UNION_##fs *_flo = \ ++ (union _FP_UNION_##fs *)(val); \ ++ \ ++ X##_f0 = _flo->bits.frac0; \ ++ X##_f1 = _flo->bits.frac1; \ ++ X##_e = _flo->bits.exp; \ ++ X##_s = _flo->bits.sign; \ ++ } while (0) ++ ++ ++/* ++ * Repack the raw bits of a native fp value. ++ */ ++ ++#define _FP_PACK_RAW_2(fs, val, X) \ ++ do { \ ++ union _FP_UNION_##fs _flo; \ ++ \ ++ _flo.bits.frac0 = X##_f0; \ ++ _flo.bits.frac1 = X##_f1; \ ++ _flo.bits.exp = X##_e; \ ++ _flo.bits.sign = X##_s; \ ++ \ ++ (val) = _flo.flt; \ ++ } while (0) ++ ++#define _FP_PACK_RAW_2_P(fs, val, X) \ ++ do { \ ++ union _FP_UNION_##fs *_flo = \ ++ (union _FP_UNION_##fs *)(val); \ ++ \ ++ _flo->bits.frac0 = X##_f0; \ ++ _flo->bits.frac1 = X##_f1; \ ++ _flo->bits.exp = X##_e; \ ++ _flo->bits.sign = X##_s; \ ++ } while (0) ++ ++ ++/* ++ * Multiplication algorithms: ++ */ ++ ++/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ ++ ++#define _FP_MUL_MEAT_2_wide(wfracbits, R, X, Y, doit) \ ++ do { \ ++ _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ ++ \ ++ doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \ ++ doit(_b_f1, _b_f0, X##_f0, Y##_f1); \ ++ doit(_c_f1, _c_f0, X##_f1, Y##_f0); \ ++ doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1); \ ++ \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ ++ _FP_FRAC_WORD_4(_z,1), 0, _b_f1, _b_f0, \ ++ _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ ++ _FP_FRAC_WORD_4(_z,1)); \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ ++ _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0, \ ++ _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ ++ _FP_FRAC_WORD_4(_z,1)); \ ++ \ ++ /* Normalize since we know where the msb of the multiplicands \ ++ were (bit B), we know that the msb of the of the product is \ ++ at either 2B or 2B-1. */ \ ++ _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ ++ R##_f0 = _FP_FRAC_WORD_4(_z,0); \ ++ R##_f1 = _FP_FRAC_WORD_4(_z,1); \ ++ } while (0) ++ ++/* Given a 1W * 1W => 2W primitive, do the extended multiplication. ++ Do only 3 multiplications instead of four. This one is for machines ++ where multiplication is much more expensive than subtraction. */ ++ ++#define _FP_MUL_MEAT_2_wide_3mul(wfracbits, R, X, Y, doit) \ ++ do { \ ++ _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ ++ _FP_W_TYPE _d; \ ++ int _c1, _c2; \ ++ \ ++ _b_f0 = X##_f0 + X##_f1; \ ++ _c1 = _b_f0 < X##_f0; \ ++ _b_f1 = Y##_f0 + Y##_f1; \ ++ _c2 = _b_f1 < Y##_f0; \ ++ doit(_d, _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \ ++ doit(_FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1), _b_f0, _b_f1); \ ++ doit(_c_f1, _c_f0, X##_f1, Y##_f1); \ ++ \ ++ _b_f0 &= -_c2; \ ++ _b_f1 &= -_c1; \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ ++ _FP_FRAC_WORD_4(_z,1), (_c1 & _c2), 0, _d, \ ++ 0, _FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1)); \ ++ __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ ++ _b_f0); \ ++ __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ ++ _b_f1); \ ++ __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ ++ _FP_FRAC_WORD_4(_z,1), \ ++ 0, _d, _FP_FRAC_WORD_4(_z,0)); \ ++ __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ ++ _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0); \ ++ __FP_FRAC_ADD_2(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), \ ++ _c_f1, _c_f0, \ ++ _FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2)); \ ++ \ ++ /* Normalize since we know where the msb of the multiplicands \ ++ were (bit B), we know that the msb of the of the product is \ ++ at either 2B or 2B-1. */ \ ++ _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ ++ R##_f0 = _FP_FRAC_WORD_4(_z,0); \ ++ R##_f1 = _FP_FRAC_WORD_4(_z,1); \ ++ } while (0) ++ ++#define _FP_MUL_MEAT_2_gmp(wfracbits, R, X, Y) \ ++ do { \ ++ _FP_FRAC_DECL_4(_z); \ ++ _FP_W_TYPE _x[2], _y[2]; \ ++ _x[0] = X##_f0; _x[1] = X##_f1; \ ++ _y[0] = Y##_f0; _y[1] = Y##_f1; \ ++ \ ++ mpn_mul_n(_z_f, _x, _y, 2); \ ++ \ ++ /* Normalize since we know where the msb of the multiplicands \ ++ were (bit B), we know that the msb of the of the product is \ ++ at either 2B or 2B-1. */ \ ++ _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ ++ R##_f0 = _z_f[0]; \ ++ R##_f1 = _z_f[1]; \ ++ } while (0) ++ ++/* Do at most 120x120=240 bits multiplication using double floating ++ point multiplication. This is useful if floating point ++ multiplication has much bigger throughput than integer multiply. ++ It is supposed to work for _FP_W_TYPE_SIZE 64 and wfracbits ++ between 106 and 120 only. ++ Caller guarantees that X and Y has (1LLL << (wfracbits - 1)) set. ++ SETFETZ is a macro which will disable all FPU exceptions and set rounding ++ towards zero, RESETFE should optionally reset it back. */ ++ ++#define _FP_MUL_MEAT_2_120_240_double(wfracbits, R, X, Y, setfetz, resetfe) \ ++ do { \ ++ static const double _const[] = { \ ++ /* 2^-24 */ 5.9604644775390625e-08, \ ++ /* 2^-48 */ 3.5527136788005009e-15, \ ++ /* 2^-72 */ 2.1175823681357508e-22, \ ++ /* 2^-96 */ 1.2621774483536189e-29, \ ++ /* 2^28 */ 2.68435456e+08, \ ++ /* 2^4 */ 1.600000e+01, \ ++ /* 2^-20 */ 9.5367431640625e-07, \ ++ /* 2^-44 */ 5.6843418860808015e-14, \ ++ /* 2^-68 */ 3.3881317890172014e-21, \ ++ /* 2^-92 */ 2.0194839173657902e-28, \ ++ /* 2^-116 */ 1.2037062152420224e-35}; \ ++ double _a240, _b240, _c240, _d240, _e240, _f240, \ ++ _g240, _h240, _i240, _j240, _k240; \ ++ union { double d; UDItype i; } _l240, _m240, _n240, _o240, \ ++ _p240, _q240, _r240, _s240; \ ++ UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0; \ ++ \ ++ if (wfracbits < 106 || wfracbits > 120) \ ++ abort(); \ ++ \ ++ setfetz; \ ++ \ ++ _e240 = (double)(long)(X##_f0 & 0xffffff); \ ++ _j240 = (double)(long)(Y##_f0 & 0xffffff); \ ++ _d240 = (double)(long)((X##_f0 >> 24) & 0xffffff); \ ++ _i240 = (double)(long)((Y##_f0 >> 24) & 0xffffff); \ ++ _c240 = (double)(long)(((X##_f1 << 16) & 0xffffff) | (X##_f0 >> 48)); \ ++ _h240 = (double)(long)(((Y##_f1 << 16) & 0xffffff) | (Y##_f0 >> 48)); \ ++ _b240 = (double)(long)((X##_f1 >> 8) & 0xffffff); \ ++ _g240 = (double)(long)((Y##_f1 >> 8) & 0xffffff); \ ++ _a240 = (double)(long)(X##_f1 >> 32); \ ++ _f240 = (double)(long)(Y##_f1 >> 32); \ ++ _e240 *= _const[3]; \ ++ _j240 *= _const[3]; \ ++ _d240 *= _const[2]; \ ++ _i240 *= _const[2]; \ ++ _c240 *= _const[1]; \ ++ _h240 *= _const[1]; \ ++ _b240 *= _const[0]; \ ++ _g240 *= _const[0]; \ ++ _s240.d = _e240*_j240;\ ++ _r240.d = _d240*_j240 + _e240*_i240;\ ++ _q240.d = _c240*_j240 + _d240*_i240 + _e240*_h240;\ ++ _p240.d = _b240*_j240 + _c240*_i240 + _d240*_h240 + _e240*_g240;\ ++ _o240.d = _a240*_j240 + _b240*_i240 + _c240*_h240 + _d240*_g240 + _e240*_f240;\ ++ _n240.d = _a240*_i240 + _b240*_h240 + _c240*_g240 + _d240*_f240; \ ++ _m240.d = _a240*_h240 + _b240*_g240 + _c240*_f240; \ ++ _l240.d = _a240*_g240 + _b240*_f240; \ ++ _k240 = _a240*_f240; \ ++ _r240.d += _s240.d; \ ++ _q240.d += _r240.d; \ ++ _p240.d += _q240.d; \ ++ _o240.d += _p240.d; \ ++ _n240.d += _o240.d; \ ++ _m240.d += _n240.d; \ ++ _l240.d += _m240.d; \ ++ _k240 += _l240.d; \ ++ _s240.d -= ((_const[10]+_s240.d)-_const[10]); \ ++ _r240.d -= ((_const[9]+_r240.d)-_const[9]); \ ++ _q240.d -= ((_const[8]+_q240.d)-_const[8]); \ ++ _p240.d -= ((_const[7]+_p240.d)-_const[7]); \ ++ _o240.d += _const[7]; \ ++ _n240.d += _const[6]; \ ++ _m240.d += _const[5]; \ ++ _l240.d += _const[4]; \ ++ if (_s240.d != 0.0) _y240 = 1; \ ++ if (_r240.d != 0.0) _y240 = 1; \ ++ if (_q240.d != 0.0) _y240 = 1; \ ++ if (_p240.d != 0.0) _y240 = 1; \ ++ _t240 = (DItype)_k240; \ ++ _u240 = _l240.i; \ ++ _v240 = _m240.i; \ ++ _w240 = _n240.i; \ ++ _x240 = _o240.i; \ ++ R##_f1 = (_t240 << (128 - (wfracbits - 1))) \ ++ | ((_u240 & 0xffffff) >> ((wfracbits - 1) - 104)); \ ++ R##_f0 = ((_u240 & 0xffffff) << (168 - (wfracbits - 1))) \ ++ | ((_v240 & 0xffffff) << (144 - (wfracbits - 1))) \ ++ | ((_w240 & 0xffffff) << (120 - (wfracbits - 1))) \ ++ | ((_x240 & 0xffffff) >> ((wfracbits - 1) - 96)) \ ++ | _y240; \ ++ resetfe; \ ++ } while (0) ++ ++/* ++ * Division algorithms: ++ */ ++ ++#define _FP_DIV_MEAT_2_udiv(fs, R, X, Y) \ ++ do { \ ++ _FP_W_TYPE _n_f2, _n_f1, _n_f0, _r_f1, _r_f0, _m_f1, _m_f0; \ ++ if (_FP_FRAC_GT_2(X, Y)) \ ++ { \ ++ _n_f2 = X##_f1 >> 1; \ ++ _n_f1 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1; \ ++ _n_f0 = X##_f0 << (_FP_W_TYPE_SIZE - 1); \ ++ } \ ++ else \ ++ { \ ++ R##_e--; \ ++ _n_f2 = X##_f1; \ ++ _n_f1 = X##_f0; \ ++ _n_f0 = 0; \ ++ } \ ++ \ ++ /* Normalize, i.e. make the most significant bit of the \ ++ denominator set. */ \ ++ _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs); \ ++ \ ++ udiv_qrnnd(R##_f1, _r_f1, _n_f2, _n_f1, Y##_f1); \ ++ umul_ppmm(_m_f1, _m_f0, R##_f1, Y##_f0); \ ++ _r_f0 = _n_f0; \ ++ if (_FP_FRAC_GT_2(_m, _r)) \ ++ { \ ++ R##_f1--; \ ++ _FP_FRAC_ADD_2(_r, Y, _r); \ ++ if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ ++ { \ ++ R##_f1--; \ ++ _FP_FRAC_ADD_2(_r, Y, _r); \ ++ } \ ++ } \ ++ _FP_FRAC_DEC_2(_r, _m); \ ++ \ ++ if (_r_f1 == Y##_f1) \ ++ { \ ++ /* This is a special case, not an optimization \ ++ (_r/Y##_f1 would not fit into UWtype). \ ++ As _r is guaranteed to be < Y, R##_f0 can be either \ ++ (UWtype)-1 or (UWtype)-2. But as we know what kind \ ++ of bits it is (sticky, guard, round), we don't care. \ ++ We also don't care what the reminder is, because the \ ++ guard bit will be set anyway. -jj */ \ ++ R##_f0 = -1; \ ++ } \ ++ else \ ++ { \ ++ udiv_qrnnd(R##_f0, _r_f1, _r_f1, _r_f0, Y##_f1); \ ++ umul_ppmm(_m_f1, _m_f0, R##_f0, Y##_f0); \ ++ _r_f0 = 0; \ ++ if (_FP_FRAC_GT_2(_m, _r)) \ ++ { \ ++ R##_f0--; \ ++ _FP_FRAC_ADD_2(_r, Y, _r); \ ++ if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ ++ { \ ++ R##_f0--; \ ++ _FP_FRAC_ADD_2(_r, Y, _r); \ ++ } \ ++ } \ ++ if (!_FP_FRAC_EQ_2(_r, _m)) \ ++ R##_f0 |= _FP_WORK_STICKY; \ ++ } \ ++ } while (0) ++ ++ ++#define _FP_DIV_MEAT_2_gmp(fs, R, X, Y) \ ++ do { \ ++ _FP_W_TYPE _x[4], _y[2], _z[4]; \ ++ _y[0] = Y##_f0; _y[1] = Y##_f1; \ ++ _x[0] = _x[3] = 0; \ ++ if (_FP_FRAC_GT_2(X, Y)) \ ++ { \ ++ R##_e++; \ ++ _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE) | \ ++ X##_f1 >> (_FP_W_TYPE_SIZE - \ ++ (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE))); \ ++ _x[2] = X##_f1 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE); \ ++ } \ ++ else \ ++ { \ ++ _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE) | \ ++ X##_f1 >> (_FP_W_TYPE_SIZE - \ ++ (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE))); \ ++ _x[2] = X##_f1 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE); \ ++ } \ ++ \ ++ (void) mpn_divrem (_z, 0, _x, 4, _y, 2); \ ++ R##_f1 = _z[1]; \ ++ R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0); \ ++ } while (0) ++ ++ ++/* ++ * Square root algorithms: ++ * We have just one right now, maybe Newton approximation ++ * should be added for those machines where division is fast. ++ */ ++ ++#define _FP_SQRT_MEAT_2(R, S, T, X, q) \ ++ do { \ ++ while (q) \ ++ { \ ++ T##_f1 = S##_f1 + q; \ ++ if (T##_f1 <= X##_f1) \ ++ { \ ++ S##_f1 = T##_f1 + q; \ ++ X##_f1 -= T##_f1; \ ++ R##_f1 += q; \ ++ } \ ++ _FP_FRAC_SLL_2(X, 1); \ ++ q >>= 1; \ ++ } \ ++ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ ++ while (q != _FP_WORK_ROUND) \ ++ { \ ++ T##_f0 = S##_f0 + q; \ ++ T##_f1 = S##_f1; \ ++ if (T##_f1 < X##_f1 || \ ++ (T##_f1 == X##_f1 && T##_f0 <= X##_f0)) \ ++ { \ ++ S##_f0 = T##_f0 + q; \ ++ S##_f1 += (T##_f0 > S##_f0); \ ++ _FP_FRAC_DEC_2(X, T); \ ++ R##_f0 += q; \ ++ } \ ++ _FP_FRAC_SLL_2(X, 1); \ ++ q >>= 1; \ ++ } \ ++ if (X##_f0 | X##_f1) \ ++ { \ ++ if (S##_f1 < X##_f1 || \ ++ (S##_f1 == X##_f1 && S##_f0 < X##_f0)) \ ++ R##_f0 |= _FP_WORK_ROUND; \ ++ R##_f0 |= _FP_WORK_STICKY; \ ++ } \ ++ } while (0) ++ ++ ++/* ++ * Assembly/disassembly for converting to/from integral types. ++ * No shifting or overflow handled here. ++ */ ++ ++#define _FP_FRAC_ASSEMBLE_2(r, X, rsize) \ ++(void)((rsize <= _FP_W_TYPE_SIZE) \ ++ ? ({ r = X##_f0; }) \ ++ : ({ \ ++ r = X##_f1; \ ++ r <<= _FP_W_TYPE_SIZE; \ ++ r += X##_f0; \ ++ })) ++ ++#define _FP_FRAC_DISASSEMBLE_2(X, r, rsize) \ ++ do { \ ++ X##_f0 = r; \ ++ X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ ++ } while (0) ++ ++/* ++ * Convert FP values between word sizes ++ */ ++ ++#define _FP_FRAC_COPY_1_2(D, S) (D##_f = S##_f0) ++ ++#define _FP_FRAC_COPY_2_1(D, S) ((D##_f0 = S##_f), (D##_f1 = 0)) ++ ++#define _FP_FRAC_COPY_2_2(D,S) _FP_FRAC_COPY_2(D,S) +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-4.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-4.h +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-4.h 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-4.h 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,688 @@ ++/* Software floating-point emulation. ++ Basic four-word fraction declaration and manipulation. ++ Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com), ++ Jakub Jelinek (jj@ultra.linux.cz), ++ David S. Miller (davem@redhat.com) and ++ Peter Maydell (pmaydell@chiark.greenend.org.uk). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ In addition to the permissions in the GNU Lesser General Public ++ License, the Free Software Foundation gives you unlimited ++ permission to link the compiled version of this file into ++ combinations with other programs, and to distribute those ++ combinations without any restriction coming from the use of this ++ file. (The Lesser General Public License restrictions do apply in ++ other respects; for example, they cover modification of the file, ++ and distribution when not linked into a combine executable.) ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#define _FP_FRAC_DECL_4(X) _FP_W_TYPE X##_f[4] ++#define _FP_FRAC_COPY_4(D,S) \ ++ (D##_f[0] = S##_f[0], D##_f[1] = S##_f[1], \ ++ D##_f[2] = S##_f[2], D##_f[3] = S##_f[3]) ++#define _FP_FRAC_SET_4(X,I) __FP_FRAC_SET_4(X, I) ++#define _FP_FRAC_HIGH_4(X) (X##_f[3]) ++#define _FP_FRAC_LOW_4(X) (X##_f[0]) ++#define _FP_FRAC_WORD_4(X,w) (X##_f[w]) ++ ++#define _FP_FRAC_SLL_4(X,N) \ ++ do { \ ++ _FP_I_TYPE _up, _down, _skip, _i; \ ++ _skip = (N) / _FP_W_TYPE_SIZE; \ ++ _up = (N) % _FP_W_TYPE_SIZE; \ ++ _down = _FP_W_TYPE_SIZE - _up; \ ++ if (!_up) \ ++ for (_i = 3; _i >= _skip; --_i) \ ++ X##_f[_i] = X##_f[_i-_skip]; \ ++ else \ ++ { \ ++ for (_i = 3; _i > _skip; --_i) \ ++ X##_f[_i] = X##_f[_i-_skip] << _up \ ++ | X##_f[_i-_skip-1] >> _down; \ ++ X##_f[_i--] = X##_f[0] << _up; \ ++ } \ ++ for (; _i >= 0; --_i) \ ++ X##_f[_i] = 0; \ ++ } while (0) ++ ++/* This one was broken too */ ++#define _FP_FRAC_SRL_4(X,N) \ ++ do { \ ++ _FP_I_TYPE _up, _down, _skip, _i; \ ++ _skip = (N) / _FP_W_TYPE_SIZE; \ ++ _down = (N) % _FP_W_TYPE_SIZE; \ ++ _up = _FP_W_TYPE_SIZE - _down; \ ++ if (!_down) \ ++ for (_i = 0; _i <= 3-_skip; ++_i) \ ++ X##_f[_i] = X##_f[_i+_skip]; \ ++ else \ ++ { \ ++ for (_i = 0; _i < 3-_skip; ++_i) \ ++ X##_f[_i] = X##_f[_i+_skip] >> _down \ ++ | X##_f[_i+_skip+1] << _up; \ ++ X##_f[_i++] = X##_f[3] >> _down; \ ++ } \ ++ for (; _i < 4; ++_i) \ ++ X##_f[_i] = 0; \ ++ } while (0) ++ ++ ++/* Right shift with sticky-lsb. ++ * What this actually means is that we do a standard right-shift, ++ * but that if any of the bits that fall off the right hand side ++ * were one then we always set the LSbit. ++ */ ++#define _FP_FRAC_SRST_4(X,S,N,size) \ ++ do { \ ++ _FP_I_TYPE _up, _down, _skip, _i; \ ++ _FP_W_TYPE _s; \ ++ _skip = (N) / _FP_W_TYPE_SIZE; \ ++ _down = (N) % _FP_W_TYPE_SIZE; \ ++ _up = _FP_W_TYPE_SIZE - _down; \ ++ for (_s = _i = 0; _i < _skip; ++_i) \ ++ _s |= X##_f[_i]; \ ++ if (!_down) \ ++ for (_i = 0; _i <= 3-_skip; ++_i) \ ++ X##_f[_i] = X##_f[_i+_skip]; \ ++ else \ ++ { \ ++ _s |= X##_f[_i] << _up; \ ++ for (_i = 0; _i < 3-_skip; ++_i) \ ++ X##_f[_i] = X##_f[_i+_skip] >> _down \ ++ | X##_f[_i+_skip+1] << _up; \ ++ X##_f[_i++] = X##_f[3] >> _down; \ ++ } \ ++ for (; _i < 4; ++_i) \ ++ X##_f[_i] = 0; \ ++ S = (_s != 0); \ ++ } while (0) ++ ++#define _FP_FRAC_SRS_4(X,N,size) \ ++ do { \ ++ int _sticky; \ ++ _FP_FRAC_SRST_4(X, _sticky, N, size); \ ++ X##_f[0] |= _sticky; \ ++ } while (0) ++ ++#define _FP_FRAC_ADD_4(R,X,Y) \ ++ __FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \ ++ X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ ++ Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) ++ ++#define _FP_FRAC_SUB_4(R,X,Y) \ ++ __FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \ ++ X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ ++ Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) ++ ++#define _FP_FRAC_DEC_4(X,Y) \ ++ __FP_FRAC_DEC_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ ++ Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) ++ ++#define _FP_FRAC_ADDI_4(X,I) \ ++ __FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I) ++ ++#define _FP_ZEROFRAC_4 0,0,0,0 ++#define _FP_MINFRAC_4 0,0,0,1 ++#define _FP_MAXFRAC_4 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0) ++ ++#define _FP_FRAC_ZEROP_4(X) ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0) ++#define _FP_FRAC_NEGP_4(X) ((_FP_WS_TYPE)X##_f[3] < 0) ++#define _FP_FRAC_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs) ++#define _FP_FRAC_CLEAR_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs) ++ ++#define _FP_FRAC_EQ_4(X,Y) \ ++ (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1] \ ++ && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3]) ++ ++#define _FP_FRAC_GT_4(X,Y) \ ++ (X##_f[3] > Y##_f[3] || \ ++ (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \ ++ (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \ ++ (X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0]) \ ++ )) \ ++ )) \ ++ ) ++ ++#define _FP_FRAC_GE_4(X,Y) \ ++ (X##_f[3] > Y##_f[3] || \ ++ (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \ ++ (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \ ++ (X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0]) \ ++ )) \ ++ )) \ ++ ) ++ ++ ++#define _FP_FRAC_CLZ_4(R,X) \ ++ do { \ ++ if (X##_f[3]) \ ++ { \ ++ __FP_CLZ(R,X##_f[3]); \ ++ } \ ++ else if (X##_f[2]) \ ++ { \ ++ __FP_CLZ(R,X##_f[2]); \ ++ R += _FP_W_TYPE_SIZE; \ ++ } \ ++ else if (X##_f[1]) \ ++ { \ ++ __FP_CLZ(R,X##_f[1]); \ ++ R += _FP_W_TYPE_SIZE*2; \ ++ } \ ++ else \ ++ { \ ++ __FP_CLZ(R,X##_f[0]); \ ++ R += _FP_W_TYPE_SIZE*3; \ ++ } \ ++ } while(0) ++ ++ ++#define _FP_UNPACK_RAW_4(fs, X, val) \ ++ do { \ ++ union _FP_UNION_##fs _flo; _flo.flt = (val); \ ++ X##_f[0] = _flo.bits.frac0; \ ++ X##_f[1] = _flo.bits.frac1; \ ++ X##_f[2] = _flo.bits.frac2; \ ++ X##_f[3] = _flo.bits.frac3; \ ++ X##_e = _flo.bits.exp; \ ++ X##_s = _flo.bits.sign; \ ++ } while (0) ++ ++#define _FP_UNPACK_RAW_4_P(fs, X, val) \ ++ do { \ ++ union _FP_UNION_##fs *_flo = \ ++ (union _FP_UNION_##fs *)(val); \ ++ \ ++ X##_f[0] = _flo->bits.frac0; \ ++ X##_f[1] = _flo->bits.frac1; \ ++ X##_f[2] = _flo->bits.frac2; \ ++ X##_f[3] = _flo->bits.frac3; \ ++ X##_e = _flo->bits.exp; \ ++ X##_s = _flo->bits.sign; \ ++ } while (0) ++ ++#define _FP_PACK_RAW_4(fs, val, X) \ ++ do { \ ++ union _FP_UNION_##fs _flo; \ ++ _flo.bits.frac0 = X##_f[0]; \ ++ _flo.bits.frac1 = X##_f[1]; \ ++ _flo.bits.frac2 = X##_f[2]; \ ++ _flo.bits.frac3 = X##_f[3]; \ ++ _flo.bits.exp = X##_e; \ ++ _flo.bits.sign = X##_s; \ ++ (val) = _flo.flt; \ ++ } while (0) ++ ++#define _FP_PACK_RAW_4_P(fs, val, X) \ ++ do { \ ++ union _FP_UNION_##fs *_flo = \ ++ (union _FP_UNION_##fs *)(val); \ ++ \ ++ _flo->bits.frac0 = X##_f[0]; \ ++ _flo->bits.frac1 = X##_f[1]; \ ++ _flo->bits.frac2 = X##_f[2]; \ ++ _flo->bits.frac3 = X##_f[3]; \ ++ _flo->bits.exp = X##_e; \ ++ _flo->bits.sign = X##_s; \ ++ } while (0) ++ ++/* ++ * Multiplication algorithms: ++ */ ++ ++/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ ++ ++#define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit) \ ++ do { \ ++ _FP_FRAC_DECL_8(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ ++ _FP_FRAC_DECL_2(_d); _FP_FRAC_DECL_2(_e); _FP_FRAC_DECL_2(_f); \ ++ \ ++ doit(_FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0), X##_f[0], Y##_f[0]); \ ++ doit(_b_f1, _b_f0, X##_f[0], Y##_f[1]); \ ++ doit(_c_f1, _c_f0, X##_f[1], Y##_f[0]); \ ++ doit(_d_f1, _d_f0, X##_f[1], Y##_f[1]); \ ++ doit(_e_f1, _e_f0, X##_f[0], Y##_f[2]); \ ++ doit(_f_f1, _f_f0, X##_f[2], Y##_f[0]); \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \ ++ _FP_FRAC_WORD_8(_z,1), 0,_b_f1,_b_f0, \ ++ 0,0,_FP_FRAC_WORD_8(_z,1)); \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \ ++ _FP_FRAC_WORD_8(_z,1), 0,_c_f1,_c_f0, \ ++ _FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \ ++ _FP_FRAC_WORD_8(_z,1)); \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ ++ _FP_FRAC_WORD_8(_z,2), 0,_d_f1,_d_f0, \ ++ 0,_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2)); \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ ++ _FP_FRAC_WORD_8(_z,2), 0,_e_f1,_e_f0, \ ++ _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ ++ _FP_FRAC_WORD_8(_z,2)); \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ ++ _FP_FRAC_WORD_8(_z,2), 0,_f_f1,_f_f0, \ ++ _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ ++ _FP_FRAC_WORD_8(_z,2)); \ ++ doit(_b_f1, _b_f0, X##_f[0], Y##_f[3]); \ ++ doit(_c_f1, _c_f0, X##_f[3], Y##_f[0]); \ ++ doit(_d_f1, _d_f0, X##_f[1], Y##_f[2]); \ ++ doit(_e_f1, _e_f0, X##_f[2], Y##_f[1]); \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ ++ _FP_FRAC_WORD_8(_z,3), 0,_b_f1,_b_f0, \ ++ 0,_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3)); \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ ++ _FP_FRAC_WORD_8(_z,3), 0,_c_f1,_c_f0, \ ++ _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ ++ _FP_FRAC_WORD_8(_z,3)); \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ ++ _FP_FRAC_WORD_8(_z,3), 0,_d_f1,_d_f0, \ ++ _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ ++ _FP_FRAC_WORD_8(_z,3)); \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ ++ _FP_FRAC_WORD_8(_z,3), 0,_e_f1,_e_f0, \ ++ _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ ++ _FP_FRAC_WORD_8(_z,3)); \ ++ doit(_b_f1, _b_f0, X##_f[2], Y##_f[2]); \ ++ doit(_c_f1, _c_f0, X##_f[1], Y##_f[3]); \ ++ doit(_d_f1, _d_f0, X##_f[3], Y##_f[1]); \ ++ doit(_e_f1, _e_f0, X##_f[2], Y##_f[3]); \ ++ doit(_f_f1, _f_f0, X##_f[3], Y##_f[2]); \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ ++ _FP_FRAC_WORD_8(_z,4), 0,_b_f1,_b_f0, \ ++ 0,_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4)); \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ ++ _FP_FRAC_WORD_8(_z,4), 0,_c_f1,_c_f0, \ ++ _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ ++ _FP_FRAC_WORD_8(_z,4)); \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ ++ _FP_FRAC_WORD_8(_z,4), 0,_d_f1,_d_f0, \ ++ _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ ++ _FP_FRAC_WORD_8(_z,4)); \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ ++ _FP_FRAC_WORD_8(_z,5), 0,_e_f1,_e_f0, \ ++ 0,_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5)); \ ++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ ++ _FP_FRAC_WORD_8(_z,5), 0,_f_f1,_f_f0, \ ++ _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ ++ _FP_FRAC_WORD_8(_z,5)); \ ++ doit(_b_f1, _b_f0, X##_f[3], Y##_f[3]); \ ++ __FP_FRAC_ADD_2(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ ++ _b_f1,_b_f0, \ ++ _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6)); \ ++ \ ++ /* Normalize since we know where the msb of the multiplicands \ ++ were (bit B), we know that the msb of the of the product is \ ++ at either 2B or 2B-1. */ \ ++ _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \ ++ __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \ ++ _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \ ++ } while (0) ++ ++#define _FP_MUL_MEAT_4_gmp(wfracbits, R, X, Y) \ ++ do { \ ++ _FP_FRAC_DECL_8(_z); \ ++ \ ++ mpn_mul_n(_z_f, _x_f, _y_f, 4); \ ++ \ ++ /* Normalize since we know where the msb of the multiplicands \ ++ were (bit B), we know that the msb of the of the product is \ ++ at either 2B or 2B-1. */ \ ++ _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \ ++ __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \ ++ _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \ ++ } while (0) ++ ++/* ++ * Helper utility for _FP_DIV_MEAT_4_udiv: ++ * pppp = m * nnn ++ */ ++#define umul_ppppmnnn(p3,p2,p1,p0,m,n2,n1,n0) \ ++ do { \ ++ UWtype _t; \ ++ umul_ppmm(p1,p0,m,n0); \ ++ umul_ppmm(p2,_t,m,n1); \ ++ __FP_FRAC_ADDI_2(p2,p1,_t); \ ++ umul_ppmm(p3,_t,m,n2); \ ++ __FP_FRAC_ADDI_2(p3,p2,_t); \ ++ } while (0) ++ ++/* ++ * Division algorithms: ++ */ ++ ++#define _FP_DIV_MEAT_4_udiv(fs, R, X, Y) \ ++ do { \ ++ int _i; \ ++ _FP_FRAC_DECL_4(_n); _FP_FRAC_DECL_4(_m); \ ++ _FP_FRAC_SET_4(_n, _FP_ZEROFRAC_4); \ ++ if (_FP_FRAC_GT_4(X, Y)) \ ++ { \ ++ _n_f[3] = X##_f[0] << (_FP_W_TYPE_SIZE - 1); \ ++ _FP_FRAC_SRL_4(X, 1); \ ++ } \ ++ else \ ++ R##_e--; \ ++ \ ++ /* Normalize, i.e. make the most significant bit of the \ ++ denominator set. */ \ ++ _FP_FRAC_SLL_4(Y, _FP_WFRACXBITS_##fs); \ ++ \ ++ for (_i = 3; ; _i--) \ ++ { \ ++ if (X##_f[3] == Y##_f[3]) \ ++ { \ ++ /* This is a special case, not an optimization \ ++ (X##_f[3]/Y##_f[3] would not fit into UWtype). \ ++ As X## is guaranteed to be < Y, R##_f[_i] can be either \ ++ (UWtype)-1 or (UWtype)-2. */ \ ++ R##_f[_i] = -1; \ ++ if (!_i) \ ++ break; \ ++ __FP_FRAC_SUB_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ ++ Y##_f[2], Y##_f[1], Y##_f[0], 0, \ ++ X##_f[2], X##_f[1], X##_f[0], _n_f[_i]); \ ++ _FP_FRAC_SUB_4(X, Y, X); \ ++ if (X##_f[3] > Y##_f[3]) \ ++ { \ ++ R##_f[_i] = -2; \ ++ _FP_FRAC_ADD_4(X, Y, X); \ ++ } \ ++ } \ ++ else \ ++ { \ ++ udiv_qrnnd(R##_f[_i], X##_f[3], X##_f[3], X##_f[2], Y##_f[3]); \ ++ umul_ppppmnnn(_m_f[3], _m_f[2], _m_f[1], _m_f[0], \ ++ R##_f[_i], Y##_f[2], Y##_f[1], Y##_f[0]); \ ++ X##_f[2] = X##_f[1]; \ ++ X##_f[1] = X##_f[0]; \ ++ X##_f[0] = _n_f[_i]; \ ++ if (_FP_FRAC_GT_4(_m, X)) \ ++ { \ ++ R##_f[_i]--; \ ++ _FP_FRAC_ADD_4(X, Y, X); \ ++ if (_FP_FRAC_GE_4(X, Y) && _FP_FRAC_GT_4(_m, X)) \ ++ { \ ++ R##_f[_i]--; \ ++ _FP_FRAC_ADD_4(X, Y, X); \ ++ } \ ++ } \ ++ _FP_FRAC_DEC_4(X, _m); \ ++ if (!_i) \ ++ { \ ++ if (!_FP_FRAC_EQ_4(X, _m)) \ ++ R##_f[0] |= _FP_WORK_STICKY; \ ++ break; \ ++ } \ ++ } \ ++ } \ ++ } while (0) ++ ++ ++/* ++ * Square root algorithms: ++ * We have just one right now, maybe Newton approximation ++ * should be added for those machines where division is fast. ++ */ ++ ++#define _FP_SQRT_MEAT_4(R, S, T, X, q) \ ++ do { \ ++ while (q) \ ++ { \ ++ T##_f[3] = S##_f[3] + q; \ ++ if (T##_f[3] <= X##_f[3]) \ ++ { \ ++ S##_f[3] = T##_f[3] + q; \ ++ X##_f[3] -= T##_f[3]; \ ++ R##_f[3] += q; \ ++ } \ ++ _FP_FRAC_SLL_4(X, 1); \ ++ q >>= 1; \ ++ } \ ++ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ ++ while (q) \ ++ { \ ++ T##_f[2] = S##_f[2] + q; \ ++ T##_f[3] = S##_f[3]; \ ++ if (T##_f[3] < X##_f[3] || \ ++ (T##_f[3] == X##_f[3] && T##_f[2] <= X##_f[2])) \ ++ { \ ++ S##_f[2] = T##_f[2] + q; \ ++ S##_f[3] += (T##_f[2] > S##_f[2]); \ ++ __FP_FRAC_DEC_2(X##_f[3], X##_f[2], \ ++ T##_f[3], T##_f[2]); \ ++ R##_f[2] += q; \ ++ } \ ++ _FP_FRAC_SLL_4(X, 1); \ ++ q >>= 1; \ ++ } \ ++ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ ++ while (q) \ ++ { \ ++ T##_f[1] = S##_f[1] + q; \ ++ T##_f[2] = S##_f[2]; \ ++ T##_f[3] = S##_f[3]; \ ++ if (T##_f[3] < X##_f[3] || \ ++ (T##_f[3] == X##_f[3] && (T##_f[2] < X##_f[2] || \ ++ (T##_f[2] == X##_f[2] && T##_f[1] <= X##_f[1])))) \ ++ { \ ++ S##_f[1] = T##_f[1] + q; \ ++ S##_f[2] += (T##_f[1] > S##_f[1]); \ ++ S##_f[3] += (T##_f[2] > S##_f[2]); \ ++ __FP_FRAC_DEC_3(X##_f[3], X##_f[2], X##_f[1], \ ++ T##_f[3], T##_f[2], T##_f[1]); \ ++ R##_f[1] += q; \ ++ } \ ++ _FP_FRAC_SLL_4(X, 1); \ ++ q >>= 1; \ ++ } \ ++ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ ++ while (q != _FP_WORK_ROUND) \ ++ { \ ++ T##_f[0] = S##_f[0] + q; \ ++ T##_f[1] = S##_f[1]; \ ++ T##_f[2] = S##_f[2]; \ ++ T##_f[3] = S##_f[3]; \ ++ if (_FP_FRAC_GE_4(X,T)) \ ++ { \ ++ S##_f[0] = T##_f[0] + q; \ ++ S##_f[1] += (T##_f[0] > S##_f[0]); \ ++ S##_f[2] += (T##_f[1] > S##_f[1]); \ ++ S##_f[3] += (T##_f[2] > S##_f[2]); \ ++ _FP_FRAC_DEC_4(X, T); \ ++ R##_f[0] += q; \ ++ } \ ++ _FP_FRAC_SLL_4(X, 1); \ ++ q >>= 1; \ ++ } \ ++ if (!_FP_FRAC_ZEROP_4(X)) \ ++ { \ ++ if (_FP_FRAC_GT_4(X,S)) \ ++ R##_f[0] |= _FP_WORK_ROUND; \ ++ R##_f[0] |= _FP_WORK_STICKY; \ ++ } \ ++ } while (0) ++ ++ ++/* ++ * Internals ++ */ ++ ++#define __FP_FRAC_SET_4(X,I3,I2,I1,I0) \ ++ (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0) ++ ++#ifndef __FP_FRAC_ADD_3 ++#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ ++ do { \ ++ _FP_W_TYPE _c1, _c2; \ ++ r0 = x0 + y0; \ ++ _c1 = r0 < x0; \ ++ r1 = x1 + y1; \ ++ _c2 = r1 < x1; \ ++ r1 += _c1; \ ++ _c2 |= r1 < _c1; \ ++ r2 = x2 + y2 + _c2; \ ++ } while (0) ++#endif ++ ++#ifndef __FP_FRAC_ADD_4 ++#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ ++ do { \ ++ _FP_W_TYPE _c1, _c2, _c3; \ ++ r0 = x0 + y0; \ ++ _c1 = r0 < x0; \ ++ r1 = x1 + y1; \ ++ _c2 = r1 < x1; \ ++ r1 += _c1; \ ++ _c2 |= r1 < _c1; \ ++ r2 = x2 + y2; \ ++ _c3 = r2 < x2; \ ++ r2 += _c2; \ ++ _c3 |= r2 < _c2; \ ++ r3 = x3 + y3 + _c3; \ ++ } while (0) ++#endif ++ ++#ifndef __FP_FRAC_SUB_3 ++#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ ++ do { \ ++ _FP_W_TYPE _c1, _c2; \ ++ r0 = x0 - y0; \ ++ _c1 = r0 > x0; \ ++ r1 = x1 - y1; \ ++ _c2 = r1 > x1; \ ++ r1 -= _c1; \ ++ _c2 |= _c1 && (y1 == x1); \ ++ r2 = x2 - y2 - _c2; \ ++ } while (0) ++#endif ++ ++#ifndef __FP_FRAC_SUB_4 ++#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ ++ do { \ ++ _FP_W_TYPE _c1, _c2, _c3; \ ++ r0 = x0 - y0; \ ++ _c1 = r0 > x0; \ ++ r1 = x1 - y1; \ ++ _c2 = r1 > x1; \ ++ r1 -= _c1; \ ++ _c2 |= _c1 && (y1 == x1); \ ++ r2 = x2 - y2; \ ++ _c3 = r2 > x2; \ ++ r2 -= _c2; \ ++ _c3 |= _c2 && (y2 == x2); \ ++ r3 = x3 - y3 - _c3; \ ++ } while (0) ++#endif ++ ++#ifndef __FP_FRAC_DEC_3 ++#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) \ ++ do { \ ++ UWtype _t0, _t1, _t2; \ ++ _t0 = x0, _t1 = x1, _t2 = x2; \ ++ __FP_FRAC_SUB_3 (x2, x1, x0, _t2, _t1, _t0, y2, y1, y0); \ ++ } while (0) ++#endif ++ ++#ifndef __FP_FRAC_DEC_4 ++#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) \ ++ do { \ ++ UWtype _t0, _t1, _t2, _t3; \ ++ _t0 = x0, _t1 = x1, _t2 = x2, _t3 = x3; \ ++ __FP_FRAC_SUB_4 (x3,x2,x1,x0,_t3,_t2,_t1,_t0, y3,y2,y1,y0); \ ++ } while (0) ++#endif ++ ++#ifndef __FP_FRAC_ADDI_4 ++#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \ ++ do { \ ++ UWtype _t; \ ++ _t = ((x0 += i) < i); \ ++ x1 += _t; _t = (x1 < _t); \ ++ x2 += _t; _t = (x2 < _t); \ ++ x3 += _t; \ ++ } while (0) ++#endif ++ ++/* Convert FP values between word sizes. This appears to be more ++ * complicated than I'd have expected it to be, so these might be ++ * wrong... These macros are in any case somewhat bogus because they ++ * use information about what various FRAC_n variables look like ++ * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do ++ * the ones in op-2.h and op-1.h. ++ */ ++#define _FP_FRAC_COPY_1_4(D, S) (D##_f = S##_f[0]) ++ ++#define _FP_FRAC_COPY_2_4(D, S) \ ++do { \ ++ D##_f0 = S##_f[0]; \ ++ D##_f1 = S##_f[1]; \ ++} while (0) ++ ++/* Assembly/disassembly for converting to/from integral types. ++ * No shifting or overflow handled here. ++ */ ++/* Put the FP value X into r, which is an integer of size rsize. */ ++#define _FP_FRAC_ASSEMBLE_4(r, X, rsize) \ ++ do { \ ++ if (rsize <= _FP_W_TYPE_SIZE) \ ++ r = X##_f[0]; \ ++ else if (rsize <= 2*_FP_W_TYPE_SIZE) \ ++ { \ ++ r = X##_f[1]; \ ++ r <<= _FP_W_TYPE_SIZE; \ ++ r += X##_f[0]; \ ++ } \ ++ else \ ++ { \ ++ /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \ ++ /* and int == 4words as a single case. */ \ ++ r = X##_f[3]; \ ++ r <<= _FP_W_TYPE_SIZE; \ ++ r += X##_f[2]; \ ++ r <<= _FP_W_TYPE_SIZE; \ ++ r += X##_f[1]; \ ++ r <<= _FP_W_TYPE_SIZE; \ ++ r += X##_f[0]; \ ++ } \ ++ } while (0) ++ ++/* "No disassemble Number Five!" */ ++/* move an integer of size rsize into X's fractional part. We rely on ++ * the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid ++ * having to mask the values we store into it. ++ */ ++#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize) \ ++ do { \ ++ X##_f[0] = r; \ ++ X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ ++ X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \ ++ X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \ ++ } while (0); ++ ++#define _FP_FRAC_COPY_4_1(D, S) \ ++do { \ ++ D##_f[0] = S##_f; \ ++ D##_f[1] = D##_f[2] = D##_f[3] = 0; \ ++} while (0) ++ ++#define _FP_FRAC_COPY_4_2(D, S) \ ++do { \ ++ D##_f[0] = S##_f0; \ ++ D##_f[1] = S##_f1; \ ++ D##_f[2] = D##_f[3] = 0; \ ++} while (0) ++ ++#define _FP_FRAC_COPY_4_4(D,S) _FP_FRAC_COPY_4(D,S) +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-8.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-8.h +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-8.h 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-8.h 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,111 @@ ++/* Software floating-point emulation. ++ Basic eight-word fraction declaration and manipulation. ++ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com), ++ Jakub Jelinek (jj@ultra.linux.cz) and ++ Peter Maydell (pmaydell@chiark.greenend.org.uk). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ In addition to the permissions in the GNU Lesser General Public ++ License, the Free Software Foundation gives you unlimited ++ permission to link the compiled version of this file into ++ combinations with other programs, and to distribute those ++ combinations without any restriction coming from the use of this ++ file. (The Lesser General Public License restrictions do apply in ++ other respects; for example, they cover modification of the file, ++ and distribution when not linked into a combine executable.) ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++/* We need just a few things from here for op-4, if we ever need some ++ other macros, they can be added. */ ++#define _FP_FRAC_DECL_8(X) _FP_W_TYPE X##_f[8] ++#define _FP_FRAC_HIGH_8(X) (X##_f[7]) ++#define _FP_FRAC_LOW_8(X) (X##_f[0]) ++#define _FP_FRAC_WORD_8(X,w) (X##_f[w]) ++ ++#define _FP_FRAC_SLL_8(X,N) \ ++ do { \ ++ _FP_I_TYPE _up, _down, _skip, _i; \ ++ _skip = (N) / _FP_W_TYPE_SIZE; \ ++ _up = (N) % _FP_W_TYPE_SIZE; \ ++ _down = _FP_W_TYPE_SIZE - _up; \ ++ if (!_up) \ ++ for (_i = 7; _i >= _skip; --_i) \ ++ X##_f[_i] = X##_f[_i-_skip]; \ ++ else \ ++ { \ ++ for (_i = 7; _i > _skip; --_i) \ ++ X##_f[_i] = X##_f[_i-_skip] << _up \ ++ | X##_f[_i-_skip-1] >> _down; \ ++ X##_f[_i--] = X##_f[0] << _up; \ ++ } \ ++ for (; _i >= 0; --_i) \ ++ X##_f[_i] = 0; \ ++ } while (0) ++ ++#define _FP_FRAC_SRL_8(X,N) \ ++ do { \ ++ _FP_I_TYPE _up, _down, _skip, _i; \ ++ _skip = (N) / _FP_W_TYPE_SIZE; \ ++ _down = (N) % _FP_W_TYPE_SIZE; \ ++ _up = _FP_W_TYPE_SIZE - _down; \ ++ if (!_down) \ ++ for (_i = 0; _i <= 7-_skip; ++_i) \ ++ X##_f[_i] = X##_f[_i+_skip]; \ ++ else \ ++ { \ ++ for (_i = 0; _i < 7-_skip; ++_i) \ ++ X##_f[_i] = X##_f[_i+_skip] >> _down \ ++ | X##_f[_i+_skip+1] << _up; \ ++ X##_f[_i++] = X##_f[7] >> _down; \ ++ } \ ++ for (; _i < 8; ++_i) \ ++ X##_f[_i] = 0; \ ++ } while (0) ++ ++ ++/* Right shift with sticky-lsb. ++ * What this actually means is that we do a standard right-shift, ++ * but that if any of the bits that fall off the right hand side ++ * were one then we always set the LSbit. ++ */ ++#define _FP_FRAC_SRS_8(X,N,size) \ ++ do { \ ++ _FP_I_TYPE _up, _down, _skip, _i; \ ++ _FP_W_TYPE _s; \ ++ _skip = (N) / _FP_W_TYPE_SIZE; \ ++ _down = (N) % _FP_W_TYPE_SIZE; \ ++ _up = _FP_W_TYPE_SIZE - _down; \ ++ for (_s = _i = 0; _i < _skip; ++_i) \ ++ _s |= X##_f[_i]; \ ++ if (!_down) \ ++ for (_i = 0; _i <= 7-_skip; ++_i) \ ++ X##_f[_i] = X##_f[_i+_skip]; \ ++ else \ ++ { \ ++ _s |= X##_f[_i] << _up; \ ++ for (_i = 0; _i < 7-_skip; ++_i) \ ++ X##_f[_i] = X##_f[_i+_skip] >> _down \ ++ | X##_f[_i+_skip+1] << _up; \ ++ X##_f[_i++] = X##_f[7] >> _down; \ ++ } \ ++ for (; _i < 8; ++_i) \ ++ X##_f[_i] = 0; \ ++ /* don't fix the LSB until the very end when we're sure f[0] is stable */ \ ++ X##_f[0] |= (_s != 0); \ ++ } while (0) ++ +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-common.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-common.h +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-common.h 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-common.h 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,1359 @@ ++/* Software floating-point emulation. Common operations. ++ Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com), ++ Jakub Jelinek (jj@ultra.linux.cz), ++ David S. Miller (davem@redhat.com) and ++ Peter Maydell (pmaydell@chiark.greenend.org.uk). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ In addition to the permissions in the GNU Lesser General Public ++ License, the Free Software Foundation gives you unlimited ++ permission to link the compiled version of this file into ++ combinations with other programs, and to distribute those ++ combinations without any restriction coming from the use of this ++ file. (The Lesser General Public License restrictions do apply in ++ other respects; for example, they cover modification of the file, ++ and distribution when not linked into a combine executable.) ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#define _FP_DECL(wc, X) \ ++ _FP_I_TYPE X##_c __attribute__((unused)), X##_s, X##_e; \ ++ _FP_FRAC_DECL_##wc(X) ++ ++/* ++ * Finish truely unpacking a native fp value by classifying the kind ++ * of fp value and normalizing both the exponent and the fraction. ++ */ ++ ++#define _FP_UNPACK_CANONICAL(fs, wc, X) \ ++do { \ ++ switch (X##_e) \ ++ { \ ++ default: \ ++ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ ++ _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \ ++ X##_e -= _FP_EXPBIAS_##fs; \ ++ X##_c = FP_CLS_NORMAL; \ ++ break; \ ++ \ ++ case 0: \ ++ if (_FP_FRAC_ZEROP_##wc(X)) \ ++ X##_c = FP_CLS_ZERO; \ ++ else \ ++ { \ ++ /* a denormalized number */ \ ++ _FP_I_TYPE _shift; \ ++ _FP_FRAC_CLZ_##wc(_shift, X); \ ++ _shift -= _FP_FRACXBITS_##fs; \ ++ _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \ ++ X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \ ++ X##_c = FP_CLS_NORMAL; \ ++ FP_SET_EXCEPTION(FP_EX_DENORM); \ ++ } \ ++ break; \ ++ \ ++ case _FP_EXPMAX_##fs: \ ++ if (_FP_FRAC_ZEROP_##wc(X)) \ ++ X##_c = FP_CLS_INF; \ ++ else \ ++ { \ ++ X##_c = FP_CLS_NAN; \ ++ /* Check for signaling NaN */ \ ++ if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \ ++ FP_SET_EXCEPTION(FP_EX_INVALID); \ ++ } \ ++ break; \ ++ } \ ++} while (0) ++ ++/* Finish unpacking an fp value in semi-raw mode: the mantissa is ++ shifted by _FP_WORKBITS but the implicit MSB is not inserted and ++ other classification is not done. */ ++#define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc(X, _FP_WORKBITS) ++ ++/* A semi-raw value has overflowed to infinity. Adjust the mantissa ++ and exponent appropriately. */ ++#define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \ ++do { \ ++ if (FP_ROUNDMODE == FP_RND_NEAREST \ ++ || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \ ++ || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \ ++ { \ ++ X##_e = _FP_EXPMAX_##fs; \ ++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ ++ } \ ++ else \ ++ { \ ++ X##_e = _FP_EXPMAX_##fs - 1; \ ++ _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ ++ } \ ++ FP_SET_EXCEPTION(FP_EX_INEXACT); \ ++ FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ ++} while (0) ++ ++/* Check for a semi-raw value being a signaling NaN and raise the ++ invalid exception if so. */ ++#define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \ ++do { \ ++ if (X##_e == _FP_EXPMAX_##fs \ ++ && !_FP_FRAC_ZEROP_##wc(X) \ ++ && !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs)) \ ++ FP_SET_EXCEPTION(FP_EX_INVALID); \ ++} while (0) ++ ++/* Choose a NaN result from an operation on two semi-raw NaN ++ values. */ ++#define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \ ++do { \ ++ /* _FP_CHOOSENAN expects raw values, so shift as required. */ \ ++ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ ++ _FP_FRAC_SRL_##wc(Y, _FP_WORKBITS); \ ++ _FP_CHOOSENAN(fs, wc, R, X, Y, OP); \ ++ _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ ++} while (0) ++ ++/* Test whether a biased exponent is normal (not zero or maximum). */ ++#define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1) ++ ++/* Prepare to pack an fp value in semi-raw mode: the mantissa is ++ rounded and shifted right, with the rounding possibly increasing ++ the exponent (including changing a finite value to infinity). */ ++#define _FP_PACK_SEMIRAW(fs, wc, X) \ ++do { \ ++ _FP_ROUND(wc, X); \ ++ if (_FP_FRAC_HIGH_##fs(X) \ ++ & (_FP_OVERFLOW_##fs >> 1)) \ ++ { \ ++ _FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1); \ ++ X##_e++; \ ++ if (X##_e == _FP_EXPMAX_##fs) \ ++ _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ ++ } \ ++ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ ++ if (!_FP_EXP_NORMAL(fs, wc, X) && !_FP_FRAC_ZEROP_##wc(X)) \ ++ { \ ++ if (X##_e == 0) \ ++ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ ++ else \ ++ { \ ++ if (!_FP_KEEPNANFRACP) \ ++ { \ ++ _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ ++ X##_s = _FP_NANSIGN_##fs; \ ++ } \ ++ else \ ++ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \ ++ } \ ++ } \ ++} while (0) ++ ++/* ++ * Before packing the bits back into the native fp result, take care ++ * of such mundane things as rounding and overflow. Also, for some ++ * kinds of fp values, the original parts may not have been fully ++ * extracted -- but that is ok, we can regenerate them now. ++ */ ++ ++#define _FP_PACK_CANONICAL(fs, wc, X) \ ++do { \ ++ switch (X##_c) \ ++ { \ ++ case FP_CLS_NORMAL: \ ++ X##_e += _FP_EXPBIAS_##fs; \ ++ if (X##_e > 0) \ ++ { \ ++ _FP_ROUND(wc, X); \ ++ if (_FP_FRAC_OVERP_##wc(fs, X)) \ ++ { \ ++ _FP_FRAC_CLEAR_OVERP_##wc(fs, X); \ ++ X##_e++; \ ++ } \ ++ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ ++ if (X##_e >= _FP_EXPMAX_##fs) \ ++ { \ ++ /* overflow */ \ ++ switch (FP_ROUNDMODE) \ ++ { \ ++ case FP_RND_NEAREST: \ ++ X##_c = FP_CLS_INF; \ ++ break; \ ++ case FP_RND_PINF: \ ++ if (!X##_s) X##_c = FP_CLS_INF; \ ++ break; \ ++ case FP_RND_MINF: \ ++ if (X##_s) X##_c = FP_CLS_INF; \ ++ break; \ ++ } \ ++ if (X##_c == FP_CLS_INF) \ ++ { \ ++ /* Overflow to infinity */ \ ++ X##_e = _FP_EXPMAX_##fs; \ ++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ ++ } \ ++ else \ ++ { \ ++ /* Overflow to maximum normal */ \ ++ X##_e = _FP_EXPMAX_##fs - 1; \ ++ _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ ++ } \ ++ FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ ++ FP_SET_EXCEPTION(FP_EX_INEXACT); \ ++ } \ ++ } \ ++ else \ ++ { \ ++ /* we've got a denormalized number */ \ ++ X##_e = -X##_e + 1; \ ++ if (X##_e <= _FP_WFRACBITS_##fs) \ ++ { \ ++ _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \ ++ _FP_ROUND(wc, X); \ ++ if (_FP_FRAC_HIGH_##fs(X) \ ++ & (_FP_OVERFLOW_##fs >> 1)) \ ++ { \ ++ X##_e = 1; \ ++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ ++ } \ ++ else \ ++ { \ ++ X##_e = 0; \ ++ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ ++ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ ++ } \ ++ } \ ++ else \ ++ { \ ++ /* underflow to zero */ \ ++ X##_e = 0; \ ++ if (!_FP_FRAC_ZEROP_##wc(X)) \ ++ { \ ++ _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ ++ _FP_ROUND(wc, X); \ ++ _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \ ++ } \ ++ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ ++ } \ ++ } \ ++ break; \ ++ \ ++ case FP_CLS_ZERO: \ ++ X##_e = 0; \ ++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ ++ break; \ ++ \ ++ case FP_CLS_INF: \ ++ X##_e = _FP_EXPMAX_##fs; \ ++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ ++ break; \ ++ \ ++ case FP_CLS_NAN: \ ++ X##_e = _FP_EXPMAX_##fs; \ ++ if (!_FP_KEEPNANFRACP) \ ++ { \ ++ _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ ++ X##_s = _FP_NANSIGN_##fs; \ ++ } \ ++ else \ ++ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \ ++ break; \ ++ } \ ++} while (0) ++ ++/* This one accepts raw argument and not cooked, returns ++ * 1 if X is a signaling NaN. ++ */ ++#define _FP_ISSIGNAN(fs, wc, X) \ ++({ \ ++ int __ret = 0; \ ++ if (X##_e == _FP_EXPMAX_##fs) \ ++ { \ ++ if (!_FP_FRAC_ZEROP_##wc(X) \ ++ && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \ ++ __ret = 1; \ ++ } \ ++ __ret; \ ++}) ++ ++ ++ ++ ++ ++/* Addition on semi-raw values. */ ++#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \ ++do { \ ++ if (X##_s == Y##_s) \ ++ { \ ++ /* Addition. */ \ ++ R##_s = X##_s; \ ++ int ediff = X##_e - Y##_e; \ ++ if (ediff > 0) \ ++ { \ ++ R##_e = X##_e; \ ++ if (Y##_e == 0) \ ++ { \ ++ /* Y is zero or denormalized. */ \ ++ if (_FP_FRAC_ZEROP_##wc(Y)) \ ++ { \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ ++ _FP_FRAC_COPY_##wc(R, X); \ ++ goto add_done; \ ++ } \ ++ else \ ++ { \ ++ FP_SET_EXCEPTION(FP_EX_DENORM); \ ++ ediff--; \ ++ if (ediff == 0) \ ++ { \ ++ _FP_FRAC_ADD_##wc(R, X, Y); \ ++ goto add3; \ ++ } \ ++ if (X##_e == _FP_EXPMAX_##fs) \ ++ { \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ ++ _FP_FRAC_COPY_##wc(R, X); \ ++ goto add_done; \ ++ } \ ++ goto add1; \ ++ } \ ++ } \ ++ else if (X##_e == _FP_EXPMAX_##fs) \ ++ { \ ++ /* X is NaN or Inf, Y is normal. */ \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ ++ _FP_FRAC_COPY_##wc(R, X); \ ++ goto add_done; \ ++ } \ ++ \ ++ /* Insert implicit MSB of Y. */ \ ++ _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ ++ \ ++ add1: \ ++ /* Shift the mantissa of Y to the right EDIFF steps; \ ++ remember to account later for the implicit MSB of X. */ \ ++ if (ediff <= _FP_WFRACBITS_##fs) \ ++ _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ ++ else if (!_FP_FRAC_ZEROP_##wc(Y)) \ ++ _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ ++ _FP_FRAC_ADD_##wc(R, X, Y); \ ++ } \ ++ else if (ediff < 0) \ ++ { \ ++ ediff = -ediff; \ ++ R##_e = Y##_e; \ ++ if (X##_e == 0) \ ++ { \ ++ /* X is zero or denormalized. */ \ ++ if (_FP_FRAC_ZEROP_##wc(X)) \ ++ { \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ ++ _FP_FRAC_COPY_##wc(R, Y); \ ++ goto add_done; \ ++ } \ ++ else \ ++ { \ ++ FP_SET_EXCEPTION(FP_EX_DENORM); \ ++ ediff--; \ ++ if (ediff == 0) \ ++ { \ ++ _FP_FRAC_ADD_##wc(R, Y, X); \ ++ goto add3; \ ++ } \ ++ if (Y##_e == _FP_EXPMAX_##fs) \ ++ { \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ ++ _FP_FRAC_COPY_##wc(R, Y); \ ++ goto add_done; \ ++ } \ ++ goto add2; \ ++ } \ ++ } \ ++ else if (Y##_e == _FP_EXPMAX_##fs) \ ++ { \ ++ /* Y is NaN or Inf, X is normal. */ \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ ++ _FP_FRAC_COPY_##wc(R, Y); \ ++ goto add_done; \ ++ } \ ++ \ ++ /* Insert implicit MSB of X. */ \ ++ _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ ++ \ ++ add2: \ ++ /* Shift the mantissa of X to the right EDIFF steps; \ ++ remember to account later for the implicit MSB of Y. */ \ ++ if (ediff <= _FP_WFRACBITS_##fs) \ ++ _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ ++ else if (!_FP_FRAC_ZEROP_##wc(X)) \ ++ _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ ++ _FP_FRAC_ADD_##wc(R, Y, X); \ ++ } \ ++ else \ ++ { \ ++ /* ediff == 0. */ \ ++ if (!_FP_EXP_NORMAL(fs, wc, X)) \ ++ { \ ++ if (X##_e == 0) \ ++ { \ ++ /* X and Y are zero or denormalized. */ \ ++ R##_e = 0; \ ++ if (_FP_FRAC_ZEROP_##wc(X)) \ ++ { \ ++ if (!_FP_FRAC_ZEROP_##wc(Y)) \ ++ FP_SET_EXCEPTION(FP_EX_DENORM); \ ++ _FP_FRAC_COPY_##wc(R, Y); \ ++ goto add_done; \ ++ } \ ++ else if (_FP_FRAC_ZEROP_##wc(Y)) \ ++ { \ ++ FP_SET_EXCEPTION(FP_EX_DENORM); \ ++ _FP_FRAC_COPY_##wc(R, X); \ ++ goto add_done; \ ++ } \ ++ else \ ++ { \ ++ FP_SET_EXCEPTION(FP_EX_DENORM); \ ++ _FP_FRAC_ADD_##wc(R, X, Y); \ ++ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ ++ { \ ++ /* Normalized result. */ \ ++ _FP_FRAC_HIGH_##fs(R) \ ++ &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ ++ R##_e = 1; \ ++ } \ ++ goto add_done; \ ++ } \ ++ } \ ++ else \ ++ { \ ++ /* X and Y are NaN or Inf. */ \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ ++ R##_e = _FP_EXPMAX_##fs; \ ++ if (_FP_FRAC_ZEROP_##wc(X)) \ ++ _FP_FRAC_COPY_##wc(R, Y); \ ++ else if (_FP_FRAC_ZEROP_##wc(Y)) \ ++ _FP_FRAC_COPY_##wc(R, X); \ ++ else \ ++ _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ ++ goto add_done; \ ++ } \ ++ } \ ++ /* The exponents of X and Y, both normal, are equal. The \ ++ implicit MSBs will always add to increase the \ ++ exponent. */ \ ++ _FP_FRAC_ADD_##wc(R, X, Y); \ ++ R##_e = X##_e + 1; \ ++ _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ ++ if (R##_e == _FP_EXPMAX_##fs) \ ++ /* Overflow to infinity (depending on rounding mode). */ \ ++ _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ ++ goto add_done; \ ++ } \ ++ add3: \ ++ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ ++ { \ ++ /* Overflow. */ \ ++ _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ ++ R##_e++; \ ++ _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ ++ if (R##_e == _FP_EXPMAX_##fs) \ ++ /* Overflow to infinity (depending on rounding mode). */ \ ++ _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ ++ } \ ++ add_done: ; \ ++ } \ ++ else \ ++ { \ ++ /* Subtraction. */ \ ++ int ediff = X##_e - Y##_e; \ ++ if (ediff > 0) \ ++ { \ ++ R##_e = X##_e; \ ++ R##_s = X##_s; \ ++ if (Y##_e == 0) \ ++ { \ ++ /* Y is zero or denormalized. */ \ ++ if (_FP_FRAC_ZEROP_##wc(Y)) \ ++ { \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ ++ _FP_FRAC_COPY_##wc(R, X); \ ++ goto sub_done; \ ++ } \ ++ else \ ++ { \ ++ FP_SET_EXCEPTION(FP_EX_DENORM); \ ++ ediff--; \ ++ if (ediff == 0) \ ++ { \ ++ _FP_FRAC_SUB_##wc(R, X, Y); \ ++ goto sub3; \ ++ } \ ++ if (X##_e == _FP_EXPMAX_##fs) \ ++ { \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ ++ _FP_FRAC_COPY_##wc(R, X); \ ++ goto sub_done; \ ++ } \ ++ goto sub1; \ ++ } \ ++ } \ ++ else if (X##_e == _FP_EXPMAX_##fs) \ ++ { \ ++ /* X is NaN or Inf, Y is normal. */ \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ ++ _FP_FRAC_COPY_##wc(R, X); \ ++ goto sub_done; \ ++ } \ ++ \ ++ /* Insert implicit MSB of Y. */ \ ++ _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ ++ \ ++ sub1: \ ++ /* Shift the mantissa of Y to the right EDIFF steps; \ ++ remember to account later for the implicit MSB of X. */ \ ++ if (ediff <= _FP_WFRACBITS_##fs) \ ++ _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ ++ else if (!_FP_FRAC_ZEROP_##wc(Y)) \ ++ _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ ++ _FP_FRAC_SUB_##wc(R, X, Y); \ ++ } \ ++ else if (ediff < 0) \ ++ { \ ++ ediff = -ediff; \ ++ R##_e = Y##_e; \ ++ R##_s = Y##_s; \ ++ if (X##_e == 0) \ ++ { \ ++ /* X is zero or denormalized. */ \ ++ if (_FP_FRAC_ZEROP_##wc(X)) \ ++ { \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ ++ _FP_FRAC_COPY_##wc(R, Y); \ ++ goto sub_done; \ ++ } \ ++ else \ ++ { \ ++ FP_SET_EXCEPTION(FP_EX_DENORM); \ ++ ediff--; \ ++ if (ediff == 0) \ ++ { \ ++ _FP_FRAC_SUB_##wc(R, Y, X); \ ++ goto sub3; \ ++ } \ ++ if (Y##_e == _FP_EXPMAX_##fs) \ ++ { \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ ++ _FP_FRAC_COPY_##wc(R, Y); \ ++ goto sub_done; \ ++ } \ ++ goto sub2; \ ++ } \ ++ } \ ++ else if (Y##_e == _FP_EXPMAX_##fs) \ ++ { \ ++ /* Y is NaN or Inf, X is normal. */ \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ ++ _FP_FRAC_COPY_##wc(R, Y); \ ++ goto sub_done; \ ++ } \ ++ \ ++ /* Insert implicit MSB of X. */ \ ++ _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ ++ \ ++ sub2: \ ++ /* Shift the mantissa of X to the right EDIFF steps; \ ++ remember to account later for the implicit MSB of Y. */ \ ++ if (ediff <= _FP_WFRACBITS_##fs) \ ++ _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ ++ else if (!_FP_FRAC_ZEROP_##wc(X)) \ ++ _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ ++ _FP_FRAC_SUB_##wc(R, Y, X); \ ++ } \ ++ else \ ++ { \ ++ /* ediff == 0. */ \ ++ if (!_FP_EXP_NORMAL(fs, wc, X)) \ ++ { \ ++ if (X##_e == 0) \ ++ { \ ++ /* X and Y are zero or denormalized. */ \ ++ R##_e = 0; \ ++ if (_FP_FRAC_ZEROP_##wc(X)) \ ++ { \ ++ _FP_FRAC_COPY_##wc(R, Y); \ ++ if (_FP_FRAC_ZEROP_##wc(Y)) \ ++ R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ ++ else \ ++ { \ ++ FP_SET_EXCEPTION(FP_EX_DENORM); \ ++ R##_s = Y##_s; \ ++ } \ ++ goto sub_done; \ ++ } \ ++ else if (_FP_FRAC_ZEROP_##wc(Y)) \ ++ { \ ++ FP_SET_EXCEPTION(FP_EX_DENORM); \ ++ _FP_FRAC_COPY_##wc(R, X); \ ++ R##_s = X##_s; \ ++ goto sub_done; \ ++ } \ ++ else \ ++ { \ ++ FP_SET_EXCEPTION(FP_EX_DENORM); \ ++ _FP_FRAC_SUB_##wc(R, X, Y); \ ++ R##_s = X##_s; \ ++ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ ++ { \ ++ /* |X| < |Y|, negate result. */ \ ++ _FP_FRAC_SUB_##wc(R, Y, X); \ ++ R##_s = Y##_s; \ ++ } \ ++ else if (_FP_FRAC_ZEROP_##wc(R)) \ ++ R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ ++ goto sub_done; \ ++ } \ ++ } \ ++ else \ ++ { \ ++ /* X and Y are NaN or Inf, of opposite signs. */ \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ ++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ ++ R##_e = _FP_EXPMAX_##fs; \ ++ if (_FP_FRAC_ZEROP_##wc(X)) \ ++ { \ ++ if (_FP_FRAC_ZEROP_##wc(Y)) \ ++ { \ ++ /* Inf - Inf. */ \ ++ R##_s = _FP_NANSIGN_##fs; \ ++ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ ++ _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ ++ FP_SET_EXCEPTION(FP_EX_INVALID); \ ++ } \ ++ else \ ++ { \ ++ /* Inf - NaN. */ \ ++ R##_s = Y##_s; \ ++ _FP_FRAC_COPY_##wc(R, Y); \ ++ } \ ++ } \ ++ else \ ++ { \ ++ if (_FP_FRAC_ZEROP_##wc(Y)) \ ++ { \ ++ /* NaN - Inf. */ \ ++ R##_s = X##_s; \ ++ _FP_FRAC_COPY_##wc(R, X); \ ++ } \ ++ else \ ++ { \ ++ /* NaN - NaN. */ \ ++ _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ ++ } \ ++ } \ ++ goto sub_done; \ ++ } \ ++ } \ ++ /* The exponents of X and Y, both normal, are equal. The \ ++ implicit MSBs cancel. */ \ ++ R##_e = X##_e; \ ++ _FP_FRAC_SUB_##wc(R, X, Y); \ ++ R##_s = X##_s; \ ++ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ ++ { \ ++ /* |X| < |Y|, negate result. */ \ ++ _FP_FRAC_SUB_##wc(R, Y, X); \ ++ R##_s = Y##_s; \ ++ } \ ++ else if (_FP_FRAC_ZEROP_##wc(R)) \ ++ { \ ++ R##_e = 0; \ ++ R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ ++ goto sub_done; \ ++ } \ ++ goto norm; \ ++ } \ ++ sub3: \ ++ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ ++ { \ ++ int diff; \ ++ /* Carry into most significant bit of larger one of X and Y, \ ++ canceling it; renormalize. */ \ ++ _FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1; \ ++ norm: \ ++ _FP_FRAC_CLZ_##wc(diff, R); \ ++ diff -= _FP_WFRACXBITS_##fs; \ ++ _FP_FRAC_SLL_##wc(R, diff); \ ++ if (R##_e <= diff) \ ++ { \ ++ /* R is denormalized. */ \ ++ diff = diff - R##_e + 1; \ ++ _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \ ++ R##_e = 0; \ ++ } \ ++ else \ ++ { \ ++ R##_e -= diff; \ ++ _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ ++ } \ ++ } \ ++ sub_done: ; \ ++ } \ ++} while (0) ++ ++#define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+') ++#define _FP_SUB(fs, wc, R, X, Y) \ ++ do { \ ++ if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \ ++ _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-'); \ ++ } while (0) ++ ++ ++/* ++ * Main negation routine. FIXME -- when we care about setting exception ++ * bits reliably, this will not do. We should examine all of the fp classes. ++ */ ++ ++#define _FP_NEG(fs, wc, R, X) \ ++ do { \ ++ _FP_FRAC_COPY_##wc(R, X); \ ++ R##_c = X##_c; \ ++ R##_e = X##_e; \ ++ R##_s = 1 ^ X##_s; \ ++ } while (0) ++ ++ ++/* ++ * Main multiplication routine. The input values should be cooked. ++ */ ++ ++#define _FP_MUL(fs, wc, R, X, Y) \ ++do { \ ++ R##_s = X##_s ^ Y##_s; \ ++ switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ ++ { \ ++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ ++ R##_c = FP_CLS_NORMAL; \ ++ R##_e = X##_e + Y##_e + 1; \ ++ \ ++ _FP_MUL_MEAT_##fs(R,X,Y); \ ++ \ ++ if (_FP_FRAC_OVERP_##wc(fs, R)) \ ++ _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ ++ else \ ++ R##_e--; \ ++ break; \ ++ \ ++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ ++ _FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \ ++ break; \ ++ \ ++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ ++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ ++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ ++ R##_s = X##_s; \ ++ \ ++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ ++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ ++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ ++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ ++ _FP_FRAC_COPY_##wc(R, X); \ ++ R##_c = X##_c; \ ++ break; \ ++ \ ++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ ++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ ++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ ++ R##_s = Y##_s; \ ++ \ ++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ ++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ ++ _FP_FRAC_COPY_##wc(R, Y); \ ++ R##_c = Y##_c; \ ++ break; \ ++ \ ++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ ++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ ++ R##_s = _FP_NANSIGN_##fs; \ ++ R##_c = FP_CLS_NAN; \ ++ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ ++ FP_SET_EXCEPTION(FP_EX_INVALID); \ ++ break; \ ++ \ ++ default: \ ++ abort(); \ ++ } \ ++} while (0) ++ ++ ++/* ++ * Main division routine. The input values should be cooked. ++ */ ++ ++#define _FP_DIV(fs, wc, R, X, Y) \ ++do { \ ++ R##_s = X##_s ^ Y##_s; \ ++ switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ ++ { \ ++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ ++ R##_c = FP_CLS_NORMAL; \ ++ R##_e = X##_e - Y##_e; \ ++ \ ++ _FP_DIV_MEAT_##fs(R,X,Y); \ ++ break; \ ++ \ ++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ ++ _FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \ ++ break; \ ++ \ ++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ ++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ ++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ ++ R##_s = X##_s; \ ++ _FP_FRAC_COPY_##wc(R, X); \ ++ R##_c = X##_c; \ ++ break; \ ++ \ ++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ ++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ ++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ ++ R##_s = Y##_s; \ ++ _FP_FRAC_COPY_##wc(R, Y); \ ++ R##_c = Y##_c; \ ++ break; \ ++ \ ++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ ++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ ++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ ++ R##_c = FP_CLS_ZERO; \ ++ break; \ ++ \ ++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ ++ FP_SET_EXCEPTION(FP_EX_DIVZERO); \ ++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ ++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ ++ R##_c = FP_CLS_INF; \ ++ break; \ ++ \ ++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ ++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ ++ R##_s = _FP_NANSIGN_##fs; \ ++ R##_c = FP_CLS_NAN; \ ++ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ ++ FP_SET_EXCEPTION(FP_EX_INVALID); \ ++ break; \ ++ \ ++ default: \ ++ abort(); \ ++ } \ ++} while (0) ++ ++ ++/* ++ * Main differential comparison routine. The inputs should be raw not ++ * cooked. The return is -1,0,1 for normal values, 2 otherwise. ++ */ ++ ++#define _FP_CMP(fs, wc, ret, X, Y, un) \ ++ do { \ ++ /* NANs are unordered */ \ ++ if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ ++ || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ ++ { \ ++ ret = un; \ ++ } \ ++ else \ ++ { \ ++ int __is_zero_x; \ ++ int __is_zero_y; \ ++ \ ++ __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \ ++ __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \ ++ \ ++ if (__is_zero_x && __is_zero_y) \ ++ ret = 0; \ ++ else if (__is_zero_x) \ ++ ret = Y##_s ? 1 : -1; \ ++ else if (__is_zero_y) \ ++ ret = X##_s ? -1 : 1; \ ++ else if (X##_s != Y##_s) \ ++ ret = X##_s ? -1 : 1; \ ++ else if (X##_e > Y##_e) \ ++ ret = X##_s ? -1 : 1; \ ++ else if (X##_e < Y##_e) \ ++ ret = X##_s ? 1 : -1; \ ++ else if (_FP_FRAC_GT_##wc(X, Y)) \ ++ ret = X##_s ? -1 : 1; \ ++ else if (_FP_FRAC_GT_##wc(Y, X)) \ ++ ret = X##_s ? 1 : -1; \ ++ else \ ++ ret = 0; \ ++ } \ ++ } while (0) ++ ++ ++/* Simplification for strict equality. */ ++ ++#define _FP_CMP_EQ(fs, wc, ret, X, Y) \ ++ do { \ ++ /* NANs are unordered */ \ ++ if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ ++ || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ ++ { \ ++ ret = 1; \ ++ } \ ++ else \ ++ { \ ++ ret = !(X##_e == Y##_e \ ++ && _FP_FRAC_EQ_##wc(X, Y) \ ++ && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \ ++ } \ ++ } while (0) ++ ++/* Version to test unordered. */ ++ ++#define _FP_CMP_UNORD(fs, wc, ret, X, Y) \ ++ do { \ ++ ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ ++ || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))); \ ++ } while (0) ++ ++/* ++ * Main square root routine. The input value should be cooked. ++ */ ++ ++#define _FP_SQRT(fs, wc, R, X) \ ++do { \ ++ _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \ ++ _FP_W_TYPE q; \ ++ switch (X##_c) \ ++ { \ ++ case FP_CLS_NAN: \ ++ _FP_FRAC_COPY_##wc(R, X); \ ++ R##_s = X##_s; \ ++ R##_c = FP_CLS_NAN; \ ++ break; \ ++ case FP_CLS_INF: \ ++ if (X##_s) \ ++ { \ ++ R##_s = _FP_NANSIGN_##fs; \ ++ R##_c = FP_CLS_NAN; /* NAN */ \ ++ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ ++ FP_SET_EXCEPTION(FP_EX_INVALID); \ ++ } \ ++ else \ ++ { \ ++ R##_s = 0; \ ++ R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \ ++ } \ ++ break; \ ++ case FP_CLS_ZERO: \ ++ R##_s = X##_s; \ ++ R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \ ++ break; \ ++ case FP_CLS_NORMAL: \ ++ R##_s = 0; \ ++ if (X##_s) \ ++ { \ ++ R##_c = FP_CLS_NAN; /* sNAN */ \ ++ R##_s = _FP_NANSIGN_##fs; \ ++ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ ++ FP_SET_EXCEPTION(FP_EX_INVALID); \ ++ break; \ ++ } \ ++ R##_c = FP_CLS_NORMAL; \ ++ if (X##_e & 1) \ ++ _FP_FRAC_SLL_##wc(X, 1); \ ++ R##_e = X##_e >> 1; \ ++ _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \ ++ _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \ ++ q = _FP_OVERFLOW_##fs >> 1; \ ++ _FP_SQRT_MEAT_##wc(R, S, T, X, q); \ ++ } \ ++ } while (0) ++ ++/* ++ * Convert from FP to integer. Input is raw. ++ */ ++ ++/* RSIGNED can have following values: ++ * 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus ++ * the result is either 0 or (2^rsize)-1 depending on the sign in such ++ * case. ++ * 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, ++ * NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 ++ * depending on the sign in such case. ++ * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is ++ * set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 ++ * depending on the sign in such case. ++ */ ++#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \ ++do { \ ++ if (X##_e < _FP_EXPBIAS_##fs) \ ++ { \ ++ r = 0; \ ++ if (X##_e == 0) \ ++ { \ ++ if (!_FP_FRAC_ZEROP_##wc(X)) \ ++ { \ ++ FP_SET_EXCEPTION(FP_EX_INEXACT); \ ++ FP_SET_EXCEPTION(FP_EX_DENORM); \ ++ } \ ++ } \ ++ else \ ++ FP_SET_EXCEPTION(FP_EX_INEXACT); \ ++ } \ ++ else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \ ++ || (!rsigned && X##_s)) \ ++ { \ ++ /* Overflow or converting to the most negative integer. */ \ ++ if (rsigned) \ ++ { \ ++ r = 1; \ ++ r <<= rsize - 1; \ ++ r -= 1 - X##_s; \ ++ } else { \ ++ r = 0; \ ++ if (X##_s) \ ++ r = ~r; \ ++ } \ ++ \ ++ if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \ ++ { \ ++ /* Possibly converting to most negative integer; check the \ ++ mantissa. */ \ ++ int inexact = 0; \ ++ (void)((_FP_FRACBITS_##fs > rsize) \ ++ ? ({ _FP_FRAC_SRST_##wc(X, inexact, \ ++ _FP_FRACBITS_##fs - rsize, \ ++ _FP_FRACBITS_##fs); 0; }) \ ++ : 0); \ ++ if (!_FP_FRAC_ZEROP_##wc(X)) \ ++ FP_SET_EXCEPTION(FP_EX_INVALID); \ ++ else if (inexact) \ ++ FP_SET_EXCEPTION(FP_EX_INEXACT); \ ++ } \ ++ else \ ++ FP_SET_EXCEPTION(FP_EX_INVALID); \ ++ } \ ++ else \ ++ { \ ++ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ ++ if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \ ++ { \ ++ _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ ++ r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \ ++ } \ ++ else \ ++ { \ ++ int inexact; \ ++ _FP_FRAC_SRST_##wc(X, inexact, \ ++ (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \ ++ - X##_e), \ ++ _FP_FRACBITS_##fs); \ ++ if (inexact) \ ++ FP_SET_EXCEPTION(FP_EX_INEXACT); \ ++ _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ ++ } \ ++ if (rsigned && X##_s) \ ++ r = -r; \ ++ } \ ++} while (0) ++ ++/* Convert integer to fp. Output is raw. RTYPE is unsigned even if ++ input is signed. */ ++#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \ ++ do { \ ++ if (r) \ ++ { \ ++ rtype ur_; \ ++ \ ++ if ((X##_s = (r < 0))) \ ++ r = -(rtype)r; \ ++ \ ++ ur_ = (rtype) r; \ ++ (void)((rsize <= _FP_W_TYPE_SIZE) \ ++ ? ({ \ ++ int lz_; \ ++ __FP_CLZ(lz_, (_FP_W_TYPE)ur_); \ ++ X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \ ++ }) \ ++ : ((rsize <= 2 * _FP_W_TYPE_SIZE) \ ++ ? ({ \ ++ int lz_; \ ++ __FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \ ++ (_FP_W_TYPE)ur_); \ ++ X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \ ++ - lz_); \ ++ }) \ ++ : (abort(), 0))); \ ++ \ ++ if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \ ++ && X##_e >= _FP_EXPMAX_##fs) \ ++ { \ ++ /* Exponent too big; overflow to infinity. (May also \ ++ happen after rounding below.) */ \ ++ _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ ++ goto pack_semiraw; \ ++ } \ ++ \ ++ if (rsize <= _FP_FRACBITS_##fs \ ++ || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \ ++ { \ ++ /* Exactly representable; shift left. */ \ ++ _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ ++ _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ ++ + _FP_FRACBITS_##fs - 1 - X##_e)); \ ++ } \ ++ else \ ++ { \ ++ /* More bits in integer than in floating type; need to \ ++ round. */ \ ++ if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \ ++ ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \ ++ - _FP_WFRACBITS_##fs + 1)) \ ++ | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \ ++ - _FP_WFRACBITS_##fs + 1))) \ ++ != 0)); \ ++ _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ ++ if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \ ++ _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ ++ + _FP_WFRACBITS_##fs - 1 - X##_e)); \ ++ _FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ ++ pack_semiraw: \ ++ _FP_PACK_SEMIRAW(fs, wc, X); \ ++ } \ ++ } \ ++ else \ ++ { \ ++ X##_s = 0; \ ++ X##_e = 0; \ ++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ ++ } \ ++ } while (0) ++ ++ ++/* Extend from a narrower floating-point format to a wider one. Input ++ and output are raw. */ ++#define FP_EXTEND(dfs,sfs,dwc,swc,D,S) \ ++do { \ ++ if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \ ++ || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \ ++ < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \ ++ || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \ ++ && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \ ++ abort(); \ ++ D##_s = S##_s; \ ++ _FP_FRAC_COPY_##dwc##_##swc(D, S); \ ++ if (_FP_EXP_NORMAL(sfs, swc, S)) \ ++ { \ ++ D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ ++ _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \ ++ } \ ++ else \ ++ { \ ++ if (S##_e == 0) \ ++ { \ ++ if (_FP_FRAC_ZEROP_##swc(S)) \ ++ D##_e = 0; \ ++ else if (_FP_EXPBIAS_##dfs \ ++ < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \ ++ { \ ++ FP_SET_EXCEPTION(FP_EX_DENORM); \ ++ _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ ++ - _FP_FRACBITS_##sfs)); \ ++ D##_e = 0; \ ++ } \ ++ else \ ++ { \ ++ int _lz; \ ++ FP_SET_EXCEPTION(FP_EX_DENORM); \ ++ _FP_FRAC_CLZ_##swc(_lz, S); \ ++ _FP_FRAC_SLL_##dwc(D, \ ++ _lz + _FP_FRACBITS_##dfs \ ++ - _FP_FRACTBITS_##sfs); \ ++ D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \ ++ + _FP_FRACXBITS_##sfs - _lz); \ ++ } \ ++ } \ ++ else \ ++ { \ ++ D##_e = _FP_EXPMAX_##dfs; \ ++ if (!_FP_FRAC_ZEROP_##swc(S)) \ ++ { \ ++ if (!(_FP_FRAC_HIGH_RAW_##sfs(S) & _FP_QNANBIT_##sfs)) \ ++ FP_SET_EXCEPTION(FP_EX_INVALID); \ ++ _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ ++ - _FP_FRACBITS_##sfs)); \ ++ } \ ++ } \ ++ } \ ++} while (0) ++ ++/* Truncate from a wider floating-point format to a narrower one. ++ Input and output are semi-raw. */ ++#define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \ ++do { \ ++ if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \ ++ || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \ ++ && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \ ++ abort(); \ ++ D##_s = S##_s; \ ++ if (_FP_EXP_NORMAL(sfs, swc, S)) \ ++ { \ ++ D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ ++ if (D##_e >= _FP_EXPMAX_##dfs) \ ++ _FP_OVERFLOW_SEMIRAW(dfs, dwc, D); \ ++ else \ ++ { \ ++ if (D##_e <= 0) \ ++ { \ ++ if (D##_e < 1 - _FP_FRACBITS_##dfs) \ ++ { \ ++ _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \ ++ _FP_FRAC_LOW_##swc(S) |= 1; \ ++ } \ ++ else \ ++ { \ ++ _FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs; \ ++ _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ ++ - _FP_WFRACBITS_##dfs + 1 - D##_e), \ ++ _FP_WFRACBITS_##sfs); \ ++ } \ ++ D##_e = 0; \ ++ } \ ++ else \ ++ _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ ++ - _FP_WFRACBITS_##dfs), \ ++ _FP_WFRACBITS_##sfs); \ ++ _FP_FRAC_COPY_##dwc##_##swc(D, S); \ ++ } \ ++ } \ ++ else \ ++ { \ ++ if (S##_e == 0) \ ++ { \ ++ D##_e = 0; \ ++ if (_FP_FRAC_ZEROP_##swc(S)) \ ++ _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ ++ else \ ++ { \ ++ FP_SET_EXCEPTION(FP_EX_DENORM); \ ++ if (_FP_EXPBIAS_##sfs \ ++ < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \ ++ { \ ++ _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ ++ - _FP_WFRACBITS_##dfs), \ ++ _FP_WFRACBITS_##sfs); \ ++ _FP_FRAC_COPY_##dwc##_##swc(D, S); \ ++ } \ ++ else \ ++ { \ ++ _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ ++ _FP_FRAC_LOW_##dwc(D) |= 1; \ ++ } \ ++ } \ ++ } \ ++ else \ ++ { \ ++ D##_e = _FP_EXPMAX_##dfs; \ ++ if (_FP_FRAC_ZEROP_##swc(S)) \ ++ _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ ++ else \ ++ { \ ++ _FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S); \ ++ _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs \ ++ - _FP_WFRACBITS_##dfs)); \ ++ _FP_FRAC_COPY_##dwc##_##swc(D, S); \ ++ /* Semi-raw NaN must have all workbits cleared. */ \ ++ _FP_FRAC_LOW_##dwc(D) \ ++ &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \ ++ _FP_FRAC_HIGH_##dfs(D) |= _FP_QNANBIT_SH_##dfs; \ ++ } \ ++ } \ ++ } \ ++} while (0) ++ ++/* ++ * Helper primitives. ++ */ ++ ++/* Count leading zeros in a word. */ ++ ++#ifndef __FP_CLZ ++/* GCC 3.4 and later provide the builtins for us. */ ++#define __FP_CLZ(r, x) \ ++ do { \ ++ if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \ ++ r = __builtin_clz (x); \ ++ else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \ ++ r = __builtin_clzl (x); \ ++ else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \ ++ r = __builtin_clzll (x); \ ++ else \ ++ abort (); \ ++ } while (0) ++#endif /* ndef __FP_CLZ */ ++ ++#define _FP_DIV_HELP_imm(q, r, n, d) \ ++ do { \ ++ q = n / d, r = n % d; \ ++ } while (0) ++ ++ ++/* A restoring bit-by-bit division primitive. */ ++ ++#define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \ ++ do { \ ++ int count = _FP_WFRACBITS_##fs; \ ++ _FP_FRAC_DECL_##wc (u); \ ++ _FP_FRAC_DECL_##wc (v); \ ++ _FP_FRAC_COPY_##wc (u, X); \ ++ _FP_FRAC_COPY_##wc (v, Y); \ ++ _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ ++ /* Normalize U and V. */ \ ++ _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \ ++ _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \ ++ /* First round. Since the operands are normalized, either the \ ++ first or second bit will be set in the fraction. Produce a \ ++ normalized result by checking which and adjusting the loop \ ++ count and exponent accordingly. */ \ ++ if (_FP_FRAC_GE_1 (u, v)) \ ++ { \ ++ _FP_FRAC_SUB_##wc (u, u, v); \ ++ _FP_FRAC_LOW_##wc (R) |= 1; \ ++ count--; \ ++ } \ ++ else \ ++ R##_e--; \ ++ /* Subsequent rounds. */ \ ++ do { \ ++ int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \ ++ _FP_FRAC_SLL_##wc (u, 1); \ ++ _FP_FRAC_SLL_##wc (R, 1); \ ++ if (msb || _FP_FRAC_GE_1 (u, v)) \ ++ { \ ++ _FP_FRAC_SUB_##wc (u, u, v); \ ++ _FP_FRAC_LOW_##wc (R) |= 1; \ ++ } \ ++ } while (--count > 0); \ ++ /* If there's anything left in U, the result is inexact. */ \ ++ _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \ ++ } while (0) ++ ++#define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y) ++#define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y) ++#define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y) +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_add.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_add.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_add.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_add.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,39 @@ ++/* Software floating-point emulation. ++ Return a + b ++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++long double _Q_add(const long double a, const long double b) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); ++ long double c; ++ ++ FP_INIT_ROUNDMODE; ++ FP_UNPACK_SEMIRAW_Q(A, a); ++ FP_UNPACK_SEMIRAW_Q(B, b); ++ FP_ADD_Q(C, A, B); ++ FP_PACK_SEMIRAW_Q(c, C); ++ FP_HANDLE_EXCEPTIONS; ++ return c; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_cmp.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_cmp.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_cmp.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_cmp.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,41 @@ ++/* Software floating-point emulation. ++ Compare a and b, return float condition code. ++ Copyright (C) 1997,1999 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++int _Q_cmp(const long double a, const long double b) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); FP_DECL_Q(B); ++ int r; ++ ++ FP_UNPACK_RAW_Q(A, a); ++ FP_UNPACK_RAW_Q(B, b); ++ FP_CMP_Q(r, B, A, 3); ++ if (r == -1) r = 2; ++ if (r == 3 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))) ++ FP_SET_EXCEPTION(FP_EX_INVALID); ++ FP_HANDLE_EXCEPTIONS; ++ ++ return r; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_cmpe.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_cmpe.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_cmpe.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_cmpe.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,42 @@ ++/* Software floating-point emulation. ++ Compare a and b, return float condition code. ++ Signal exception (unless masked) if unordered. ++ Copyright (C) 1997,1999 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++int _Q_cmpe(const long double a, const long double b) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); FP_DECL_Q(B); ++ int r; ++ ++ FP_UNPACK_RAW_Q(A, a); ++ FP_UNPACK_RAW_Q(B, b); ++ FP_CMP_Q(r, B, A, 3); ++ if (r == -1) r = 2; ++ if (r == 3) ++ FP_SET_EXCEPTION(FP_EX_INVALID); ++ FP_HANDLE_EXCEPTIONS; ++ ++ return r; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_div.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_div.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_div.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_div.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,39 @@ ++/* Software floating-point emulation. ++ Return a / b ++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++long double _Q_div(const long double a, const long double b) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); ++ long double c; ++ ++ FP_INIT_ROUNDMODE; ++ FP_UNPACK_Q(A, a); ++ FP_UNPACK_Q(B, b); ++ FP_DIV_Q(C, A, B); ++ FP_PACK_Q(c, C); ++ FP_HANDLE_EXCEPTIONS; ++ return c; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_dtoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_dtoq.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_dtoq.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_dtoq.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,44 @@ ++/* Software floating-point emulation. ++ Return (long double)(a) ++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "double.h" ++#include "quad.h" ++ ++long double _Q_dtoq(const double a) ++{ ++ FP_DECL_EX; ++ FP_DECL_D(A); ++ FP_DECL_Q(C); ++ long double c; ++ ++ FP_INIT_ROUNDMODE; ++ FP_UNPACK_RAW_D(A, a); ++#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q ++ FP_EXTEND(Q,D,4,2,C,A); ++#else ++ FP_EXTEND(Q,D,2,1,C,A); ++#endif ++ FP_PACK_RAW_Q(c, C); ++ FP_HANDLE_EXCEPTIONS; ++ return c; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_feq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_feq.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_feq.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_feq.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,40 @@ ++/* Software floating-point emulation. ++ Return 1 if a == b ++ Copyright (C) 1997,1999 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++int _Q_feq(const long double a, const long double b) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); FP_DECL_Q(B); ++ int r; ++ ++ FP_UNPACK_RAW_Q(A, a); ++ FP_UNPACK_RAW_Q(B, b); ++ FP_CMP_EQ_Q(r, A, B); ++ if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))) ++ FP_SET_EXCEPTION(FP_EX_INVALID); ++ FP_HANDLE_EXCEPTIONS; ++ ++ return !r; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fge.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fge.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fge.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fge.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,40 @@ ++/* Software floating-point emulation. ++ Return 1 if a >= b ++ Copyright (C) 1997,1999 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++int _Q_fge(const long double a, const long double b) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); FP_DECL_Q(B); ++ int r; ++ ++ FP_UNPACK_RAW_Q(A, a); ++ FP_UNPACK_RAW_Q(B, b); ++ FP_CMP_Q(r, B, A, 3); ++ if (r == 3) ++ FP_SET_EXCEPTION(FP_EX_INVALID); ++ FP_HANDLE_EXCEPTIONS; ++ ++ return (r <= 0); ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fgt.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fgt.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fgt.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fgt.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,40 @@ ++/* Software floating-point emulation. ++ Return 1 if a > b ++ Copyright (C) 1997,1999 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++int _Q_fgt(const long double a, const long double b) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); FP_DECL_Q(B); ++ int r; ++ ++ FP_UNPACK_RAW_Q(A, a); ++ FP_UNPACK_RAW_Q(B, b); ++ FP_CMP_Q(r, B, A, 3); ++ if (r == 3) ++ FP_SET_EXCEPTION(FP_EX_INVALID); ++ FP_HANDLE_EXCEPTIONS; ++ ++ return (r == -1); ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fle.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fle.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fle.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fle.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,40 @@ ++/* Software floating-point emulation. ++ Return 1 if a <= b ++ Copyright (C) 1997,1999 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++int _Q_fle(const long double a, const long double b) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); FP_DECL_Q(B); ++ int r; ++ ++ FP_UNPACK_RAW_Q(A, a); ++ FP_UNPACK_RAW_Q(B, b); ++ FP_CMP_Q(r, B, A, -2); ++ if (r == -2) ++ FP_SET_EXCEPTION(FP_EX_INVALID); ++ FP_HANDLE_EXCEPTIONS; ++ ++ return (r >= 0); ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_flt.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_flt.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_flt.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_flt.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,40 @@ ++/* Software floating-point emulation. ++ Return 1 if a < b ++ Copyright (C) 1997,1999 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++int _Q_flt(const long double a, const long double b) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); FP_DECL_Q(B); ++ int r; ++ ++ FP_UNPACK_RAW_Q(A, a); ++ FP_UNPACK_RAW_Q(B, b); ++ FP_CMP_Q(r, B, A, 3); ++ if (r == 3) ++ FP_SET_EXCEPTION(FP_EX_INVALID); ++ FP_HANDLE_EXCEPTIONS; ++ ++ return (r == 1); ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fne.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fne.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fne.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fne.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,40 @@ ++/* Software floating-point emulation. ++ Return 1 if a != b ++ Copyright (C) 1997,1999 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++int _Q_fne(const long double a, const long double b) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); FP_DECL_Q(B); ++ int r; ++ ++ FP_UNPACK_RAW_Q(A, a); ++ FP_UNPACK_RAW_Q(B, b); ++ FP_CMP_EQ_Q(r, A, B); ++ if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))) ++ FP_SET_EXCEPTION(FP_EX_INVALID); ++ FP_HANDLE_EXCEPTIONS; ++ ++ return r; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_itoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_itoq.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_itoq.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_itoq.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,38 @@ ++/* Software floating-point emulation. ++ Return (long double)(a) ++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++long double _Q_itoq(const int a) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(C); ++ int b = a; ++ long double c; ++ ++ FP_FROM_INT_Q(C, b, 32, unsigned int); ++ FP_PACK_RAW_Q(c, C); ++ FP_CLEAR_EXCEPTIONS; ++ FP_HANDLE_EXCEPTIONS; ++ return c; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_lltoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_lltoq.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_lltoq.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_lltoq.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,38 @@ ++/* Software floating-point emulation. ++ Return (long double)a ++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++long double _Q_lltoq(const long long a) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(C); ++ long double c; ++ long long b = a; ++ ++ FP_FROM_INT_Q(C, b, 64, unsigned long long); ++ FP_PACK_RAW_Q(c, C); ++ FP_CLEAR_EXCEPTIONS; ++ FP_HANDLE_EXCEPTIONS; ++ return c; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_mul.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_mul.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_mul.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_mul.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,39 @@ ++/* Software floating-point emulation. ++ Return a * b ++ Copyright (C) 1997,1999 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++long double _Q_mul(const long double a, const long double b) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); ++ long double c; ++ ++ FP_INIT_ROUNDMODE; ++ FP_UNPACK_Q(A, a); ++ FP_UNPACK_Q(B, b); ++ FP_MUL_Q(C, A, B); ++ FP_PACK_Q(c, C); ++ FP_HANDLE_EXCEPTIONS; ++ return c; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_neg.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_neg.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_neg.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_neg.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,47 @@ ++/* Software floating-point emulation. ++ Return !a ++ Copyright (C) 1997,1999 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++long double _Q_neg(const long double a) ++{ ++ FP_DECL_EX; ++ long double c = a; ++ ++#if (__BYTE_ORDER == __BIG_ENDIAN) ++ ((UWtype *)&c)[0] ^= (((UWtype)1) << (W_TYPE_SIZE - 1)); ++#elif (__BYTE_ORDER == __LITTLE_ENDIAN) && (W_TYPE_SIZE == 64) ++ ((UWtype *)&c)[1] ^= (((UWtype)1) << (W_TYPE_SIZE - 1)); ++#elif (__BYTE_ORDER == __LITTLE_ENDIAN) && (W_TYPE_SIZE == 32) ++ ((UWtype *)&c)[3] ^= (((UWtype)1) << (W_TYPE_SIZE - 1)); ++#else ++ FP_DECL_Q(A); FP_DECL_Q(C); ++ ++ FP_UNPACK_Q(A, a); ++ FP_NEG_Q(C, A); ++ FP_PACK_Q(c, C); ++#endif ++ FP_CLEAR_EXCEPTIONS; ++ FP_HANDLE_EXCEPTIONS; ++ return c; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtod.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtod.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtod.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtod.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,45 @@ ++/* Software floating-point emulation. ++ Return (double)a ++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "double.h" ++#include "quad.h" ++ ++double _Q_qtod(const long double a) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); ++ FP_DECL_D(R); ++ double r; ++ ++ FP_INIT_ROUNDMODE; ++ FP_UNPACK_SEMIRAW_Q(A, a); ++#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q ++ FP_TRUNC(D,Q,2,4,R,A); ++#else ++ FP_TRUNC(D,Q,1,2,R,A); ++#endif ++ FP_PACK_SEMIRAW_D(r, R); ++ FP_HANDLE_EXCEPTIONS; ++ ++ return r; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoi.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoi.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoi.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoi.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,38 @@ ++/* Software floating-point emulation. ++ Return (int)a ++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#define FP_ROUNDMODE FP_RND_ZERO ++#include "soft-fp.h" ++#include "quad.h" ++ ++int _Q_qtoi(const long double a) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); ++ unsigned int r; ++ ++ FP_UNPACK_RAW_Q(A, a); ++ FP_TO_INT_Q(r, A, 32, 1); ++ FP_HANDLE_EXCEPTIONS; ++ ++ return r; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoll.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoll.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoll.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoll.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,38 @@ ++/* Software floating-point emulation. ++ Return (long long)a ++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#define FP_ROUNDMODE FP_RND_ZERO ++#include "soft-fp.h" ++#include "quad.h" ++ ++long long _Q_qtoll(const long double a) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); ++ unsigned long long r; ++ ++ FP_UNPACK_RAW_Q(A, a); ++ FP_TO_INT_Q(r, A, 64, 1); ++ FP_HANDLE_EXCEPTIONS; ++ ++ return r; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtos.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtos.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtos.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtos.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,45 @@ ++/* Software floating-point emulation. ++ Return (float)a ++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "single.h" ++#include "quad.h" ++ ++float _Q_qtos(const long double a) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); ++ FP_DECL_S(R); ++ float r; ++ ++ FP_INIT_ROUNDMODE; ++ FP_UNPACK_SEMIRAW_Q(A, a); ++#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q ++ FP_TRUNC(S,Q,1,4,R,A); ++#else ++ FP_TRUNC(S,Q,1,2,R,A); ++#endif ++ FP_PACK_SEMIRAW_S(r, R); ++ FP_HANDLE_EXCEPTIONS; ++ ++ return r; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtou.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtou.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtou.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtou.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,38 @@ ++/* Software floating-point emulation. ++ Return (unsigned int)a ++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#define FP_ROUNDMODE FP_RND_ZERO ++#include "soft-fp.h" ++#include "quad.h" ++ ++unsigned int _Q_qtou(const long double a) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); ++ unsigned int r; ++ ++ FP_UNPACK_RAW_Q(A, a); ++ FP_TO_INT_Q(r, A, 32, -1); ++ FP_HANDLE_EXCEPTIONS; ++ ++ return r; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoull.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoull.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoull.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoull.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,38 @@ ++/* Software floating-point emulation. ++ Return (unsigned long long)a ++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#define FP_ROUNDMODE FP_RND_ZERO ++#include "soft-fp.h" ++#include "quad.h" ++ ++unsigned long long _Q_qtoull(const long double a) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); ++ unsigned long long r; ++ ++ FP_UNPACK_RAW_Q(A, a); ++ FP_TO_INT_Q(r, A, 64, -1); ++ FP_HANDLE_EXCEPTIONS; ++ ++ return r; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_sqrt.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_sqrt.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_sqrt.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_sqrt.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,39 @@ ++/* Software floating-point emulation. ++ Return sqrtl(a) ++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++long double _Q_sqrt(const long double a) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); FP_DECL_Q(C); ++ long double c; ++ ++ FP_INIT_ROUNDMODE; ++ FP_UNPACK_Q(A, a); ++ FP_SQRT_Q(C, A); ++ FP_PACK_Q(c, C); ++ FP_HANDLE_EXCEPTIONS; ++ return c; ++} ++strong_alias (_Q_sqrt, __ieee754_sqrtl); +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_stoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_stoq.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_stoq.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_stoq.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,43 @@ ++/* Software floating-point emulation. ++ c = (long double)(a) ++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "single.h" ++#include "quad.h" ++ ++long double _Q_stoq(const float a) ++{ ++ FP_DECL_EX; ++ FP_DECL_S(A); ++ FP_DECL_Q(C); ++ long double c; ++ ++ FP_UNPACK_RAW_S(A, a); ++#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q ++ FP_EXTEND(Q,S,4,1,C,A); ++#else ++ FP_EXTEND(Q,S,2,1,C,A); ++#endif ++ FP_PACK_RAW_Q(c, C); ++ FP_HANDLE_EXCEPTIONS; ++ return c; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_sub.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_sub.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_sub.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_sub.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,39 @@ ++/* Software floating-point emulation. ++ c = a - b ++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++long double _Q_sub(const long double a, const long double b) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); ++ long double c; ++ ++ FP_INIT_ROUNDMODE; ++ FP_UNPACK_SEMIRAW_Q(A, a); ++ FP_UNPACK_SEMIRAW_Q(B, b); ++ FP_SUB_Q(C, A, B); ++ FP_PACK_SEMIRAW_Q(c, C); ++ FP_HANDLE_EXCEPTIONS; ++ return c; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_ulltoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_ulltoq.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_ulltoq.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_ulltoq.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,38 @@ ++/* Software floating-point emulation. ++ Return (long double)(a) ++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++long double _Q_ulltoq(const unsigned long long a) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(C); ++ long double c; ++ unsigned long long b = a; ++ ++ FP_FROM_INT_Q(C, b, 64, unsigned long long); ++ FP_PACK_RAW_Q(c, C); ++ FP_CLEAR_EXCEPTIONS; ++ FP_HANDLE_EXCEPTIONS; ++ return c; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_util.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_util.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_util.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_util.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,57 @@ ++/* Software floating-point emulation. ++ Helper routine for _Q_* routines. ++ Simulate exceptions using double arithmetics. ++ Copyright (C) 1999 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++ ++unsigned long long ___Q_numbers [] = { ++0x0000000000000000ULL, /* Zero */ ++0x0010100000000000ULL, /* Very tiny number */ ++0x0010000000000000ULL, /* Minimum normalized number */ ++0x7fef000000000000ULL, /* A huge double number */ ++}; ++ ++double ___Q_simulate_exceptions(int exceptions) ++{ ++ double d, *p = (double *)___Q_numbers; ++ if (exceptions & FP_EX_INVALID) ++ d = p[0]/p[0]; ++ if (exceptions & FP_EX_OVERFLOW) ++ { ++ d = p[3] + p[3]; ++ exceptions &= ~FP_EX_INEXACT; ++ } ++ if (exceptions & FP_EX_UNDERFLOW) ++ { ++ if (exceptions & FP_EX_INEXACT) ++ { ++ d = p[2] * p[2]; ++ exceptions &= ~FP_EX_INEXACT; ++ } ++ else ++ d = p[1] - p[2]; ++ } ++ if (exceptions & FP_EX_DIVZERO) ++ d = 1.0/p[0]; ++ if (exceptions & FP_EX_INEXACT) ++ d = p[3] - p[2]; ++ return d; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_utoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_utoq.c +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_utoq.c 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_utoq.c 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,38 @@ ++/* Software floating-point emulation. ++ c = (long double)(a) ++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com) and ++ Jakub Jelinek (jj@ultra.linux.cz). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include "soft-fp.h" ++#include "quad.h" ++ ++long double _Q_utoq(const unsigned int a) ++{ ++ FP_DECL_EX; ++ FP_DECL_Q(C); ++ long double c; ++ unsigned int b = a; ++ ++ FP_FROM_INT_Q(C, b, 32, unsigned int); ++ FP_PACK_RAW_Q(c, C); ++ FP_CLEAR_EXCEPTIONS; ++ FP_HANDLE_EXCEPTIONS; ++ return c; ++} +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/quad.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/quad.h +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/quad.h 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/quad.h 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,271 @@ ++/* Software floating-point emulation. ++ Definitions for IEEE Quad Precision. ++ Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com), ++ Jakub Jelinek (jj@ultra.linux.cz), ++ David S. Miller (davem@redhat.com) and ++ Peter Maydell (pmaydell@chiark.greenend.org.uk). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ In addition to the permissions in the GNU Lesser General Public ++ License, the Free Software Foundation gives you unlimited ++ permission to link the compiled version of this file into ++ combinations with other programs, and to distribute those ++ combinations without any restriction coming from the use of this ++ file. (The Lesser General Public License restrictions do apply in ++ other respects; for example, they cover modification of the file, ++ and distribution when not linked into a combine executable.) ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#if _FP_W_TYPE_SIZE < 32 ++#error "Here's a nickel, kid. Go buy yourself a real computer." ++#endif ++ ++#if _FP_W_TYPE_SIZE < 64 ++#define _FP_FRACTBITS_Q (4*_FP_W_TYPE_SIZE) ++#else ++#define _FP_FRACTBITS_Q (2*_FP_W_TYPE_SIZE) ++#endif ++ ++#define _FP_FRACBITS_Q 113 ++#define _FP_FRACXBITS_Q (_FP_FRACTBITS_Q - _FP_FRACBITS_Q) ++#define _FP_WFRACBITS_Q (_FP_WORKBITS + _FP_FRACBITS_Q) ++#define _FP_WFRACXBITS_Q (_FP_FRACTBITS_Q - _FP_WFRACBITS_Q) ++#define _FP_EXPBITS_Q 15 ++#define _FP_EXPBIAS_Q 16383 ++#define _FP_EXPMAX_Q 32767 ++ ++#define _FP_QNANBIT_Q \ ++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2) % _FP_W_TYPE_SIZE) ++#define _FP_QNANBIT_SH_Q \ ++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) ++#define _FP_IMPLBIT_Q \ ++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1) % _FP_W_TYPE_SIZE) ++#define _FP_IMPLBIT_SH_Q \ ++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) ++#define _FP_OVERFLOW_Q \ ++ ((_FP_W_TYPE)1 << (_FP_WFRACBITS_Q % _FP_W_TYPE_SIZE)) ++ ++typedef float TFtype __attribute__((mode(TF))); ++ ++#if _FP_W_TYPE_SIZE < 64 ++ ++union _FP_UNION_Q ++{ ++ TFtype flt; ++ struct ++ { ++#if __BYTE_ORDER == __BIG_ENDIAN ++ unsigned sign : 1; ++ unsigned exp : _FP_EXPBITS_Q; ++ unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); ++ unsigned long frac2 : _FP_W_TYPE_SIZE; ++ unsigned long frac1 : _FP_W_TYPE_SIZE; ++ unsigned long frac0 : _FP_W_TYPE_SIZE; ++#else ++ unsigned long frac0 : _FP_W_TYPE_SIZE; ++ unsigned long frac1 : _FP_W_TYPE_SIZE; ++ unsigned long frac2 : _FP_W_TYPE_SIZE; ++ unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); ++ unsigned exp : _FP_EXPBITS_Q; ++ unsigned sign : 1; ++#endif /* not bigendian */ ++ } bits __attribute__((packed)); ++}; ++ ++ ++#define FP_DECL_Q(X) _FP_DECL(4,X) ++#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_4(Q,X,val) ++#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_4_P(Q,X,val) ++#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_4(Q,val,X) ++#define FP_PACK_RAW_QP(val,X) \ ++ do { \ ++ if (!FP_INHIBIT_RESULTS) \ ++ _FP_PACK_RAW_4_P(Q,val,X); \ ++ } while (0) ++ ++#define FP_UNPACK_Q(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_4(Q,X,val); \ ++ _FP_UNPACK_CANONICAL(Q,4,X); \ ++ } while (0) ++ ++#define FP_UNPACK_QP(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_4_P(Q,X,val); \ ++ _FP_UNPACK_CANONICAL(Q,4,X); \ ++ } while (0) ++ ++#define FP_UNPACK_SEMIRAW_Q(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_4(Q,X,val); \ ++ _FP_UNPACK_SEMIRAW(Q,4,X); \ ++ } while (0) ++ ++#define FP_UNPACK_SEMIRAW_QP(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_4_P(Q,X,val); \ ++ _FP_UNPACK_SEMIRAW(Q,4,X); \ ++ } while (0) ++ ++#define FP_PACK_Q(val,X) \ ++ do { \ ++ _FP_PACK_CANONICAL(Q,4,X); \ ++ _FP_PACK_RAW_4(Q,val,X); \ ++ } while (0) ++ ++#define FP_PACK_QP(val,X) \ ++ do { \ ++ _FP_PACK_CANONICAL(Q,4,X); \ ++ if (!FP_INHIBIT_RESULTS) \ ++ _FP_PACK_RAW_4_P(Q,val,X); \ ++ } while (0) ++ ++#define FP_PACK_SEMIRAW_Q(val,X) \ ++ do { \ ++ _FP_PACK_SEMIRAW(Q,4,X); \ ++ _FP_PACK_RAW_4(Q,val,X); \ ++ } while (0) ++ ++#define FP_PACK_SEMIRAW_QP(val,X) \ ++ do { \ ++ _FP_PACK_SEMIRAW(Q,4,X); \ ++ if (!FP_INHIBIT_RESULTS) \ ++ _FP_PACK_RAW_4_P(Q,val,X); \ ++ } while (0) ++ ++#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,4,X) ++#define FP_NEG_Q(R,X) _FP_NEG(Q,4,R,X) ++#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,4,R,X,Y) ++#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,4,R,X,Y) ++#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,4,R,X,Y) ++#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,4,R,X,Y) ++#define FP_SQRT_Q(R,X) _FP_SQRT(Q,4,R,X) ++#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_4(R,S,T,X,Q) ++ ++#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,4,r,X,Y,un) ++#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,4,r,X,Y) ++#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,4,r,X,Y) ++ ++#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,4,r,X,rsz,rsg) ++#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,4,X,r,rs,rt) ++ ++#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_4(X) ++#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_4(X) ++ ++#else /* not _FP_W_TYPE_SIZE < 64 */ ++union _FP_UNION_Q ++{ ++ TFtype flt /* __attribute__((mode(TF))) */ ; ++ struct { ++ _FP_W_TYPE a, b; ++ } longs; ++ struct { ++#if __BYTE_ORDER == __BIG_ENDIAN ++ unsigned sign : 1; ++ unsigned exp : _FP_EXPBITS_Q; ++ _FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE; ++ _FP_W_TYPE frac0 : _FP_W_TYPE_SIZE; ++#else ++ _FP_W_TYPE frac0 : _FP_W_TYPE_SIZE; ++ _FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE; ++ unsigned exp : _FP_EXPBITS_Q; ++ unsigned sign : 1; ++#endif ++ } bits; ++}; ++ ++#define FP_DECL_Q(X) _FP_DECL(2,X) ++#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_2(Q,X,val) ++#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_2_P(Q,X,val) ++#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_2(Q,val,X) ++#define FP_PACK_RAW_QP(val,X) \ ++ do { \ ++ if (!FP_INHIBIT_RESULTS) \ ++ _FP_PACK_RAW_2_P(Q,val,X); \ ++ } while (0) ++ ++#define FP_UNPACK_Q(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_2(Q,X,val); \ ++ _FP_UNPACK_CANONICAL(Q,2,X); \ ++ } while (0) ++ ++#define FP_UNPACK_QP(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_2_P(Q,X,val); \ ++ _FP_UNPACK_CANONICAL(Q,2,X); \ ++ } while (0) ++ ++#define FP_UNPACK_SEMIRAW_Q(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_2(Q,X,val); \ ++ _FP_UNPACK_SEMIRAW(Q,2,X); \ ++ } while (0) ++ ++#define FP_UNPACK_SEMIRAW_QP(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_2_P(Q,X,val); \ ++ _FP_UNPACK_SEMIRAW(Q,2,X); \ ++ } while (0) ++ ++#define FP_PACK_Q(val,X) \ ++ do { \ ++ _FP_PACK_CANONICAL(Q,2,X); \ ++ _FP_PACK_RAW_2(Q,val,X); \ ++ } while (0) ++ ++#define FP_PACK_QP(val,X) \ ++ do { \ ++ _FP_PACK_CANONICAL(Q,2,X); \ ++ if (!FP_INHIBIT_RESULTS) \ ++ _FP_PACK_RAW_2_P(Q,val,X); \ ++ } while (0) ++ ++#define FP_PACK_SEMIRAW_Q(val,X) \ ++ do { \ ++ _FP_PACK_SEMIRAW(Q,2,X); \ ++ _FP_PACK_RAW_2(Q,val,X); \ ++ } while (0) ++ ++#define FP_PACK_SEMIRAW_QP(val,X) \ ++ do { \ ++ _FP_PACK_SEMIRAW(Q,2,X); \ ++ if (!FP_INHIBIT_RESULTS) \ ++ _FP_PACK_RAW_2_P(Q,val,X); \ ++ } while (0) ++ ++#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,2,X) ++#define FP_NEG_Q(R,X) _FP_NEG(Q,2,R,X) ++#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,2,R,X,Y) ++#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,2,R,X,Y) ++#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,2,R,X,Y) ++#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,2,R,X,Y) ++#define FP_SQRT_Q(R,X) _FP_SQRT(Q,2,R,X) ++#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q) ++ ++#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,2,r,X,Y,un) ++#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,2,r,X,Y) ++#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,2,r,X,Y) ++ ++#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,2,r,X,rsz,rsg) ++#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,2,X,r,rs,rt) ++ ++#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_2(X) ++#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_2(X) ++ ++#endif /* not _FP_W_TYPE_SIZE < 64 */ +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,213 @@ ++/* Machine-dependent software floating-point definitions. ++ Sparc userland (_Q_*) version. ++ Copyright (C) 1997,1998,1999, 2002, 2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com), ++ Jakub Jelinek (jj@ultra.linux.cz) and ++ David S. Miller (davem@redhat.com). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include ++#include ++ ++#define _FP_W_TYPE_SIZE 32 ++#define _FP_W_TYPE unsigned long ++#define _FP_WS_TYPE signed long ++#define _FP_I_TYPE long ++ ++#define _FP_MUL_MEAT_S(R,X,Y) \ ++ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) ++#define _FP_MUL_MEAT_D(R,X,Y) \ ++ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) ++#define _FP_MUL_MEAT_Q(R,X,Y) \ ++ _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) ++ ++#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y) ++#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y) ++#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y) ++ ++#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1) ++#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1 ++#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1 ++#define _FP_NANSIGN_S 0 ++#define _FP_NANSIGN_D 0 ++#define _FP_NANSIGN_Q 0 ++ ++#define _FP_KEEPNANFRACP 1 ++ ++/* If one NaN is signaling and the other is not, ++ * we choose that one, otherwise we choose X. ++ */ ++/* For _Qp_* and _Q_*, this should prefer X, for ++ * CPU instruction emulation this should prefer Y. ++ * (see SPAMv9 B.2.2 section). ++ */ ++#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ ++ do { \ ++ if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \ ++ && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \ ++ { \ ++ R##_s = Y##_s; \ ++ _FP_FRAC_COPY_##wc(R,Y); \ ++ } \ ++ else \ ++ { \ ++ R##_s = X##_s; \ ++ _FP_FRAC_COPY_##wc(R,X); \ ++ } \ ++ R##_c = FP_CLS_NAN; \ ++ } while (0) ++ ++/* Some assembly to speed things up. */ ++#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ ++ __asm__ ("addcc %r7,%8,%2\n\ ++ addxcc %r5,%6,%1\n\ ++ addx %r3,%4,%0" \ ++ : "=r" ((USItype)(r2)), \ ++ "=&r" ((USItype)(r1)), \ ++ "=&r" ((USItype)(r0)) \ ++ : "%rJ" ((USItype)(x2)), \ ++ "rI" ((USItype)(y2)), \ ++ "%rJ" ((USItype)(x1)), \ ++ "rI" ((USItype)(y1)), \ ++ "%rJ" ((USItype)(x0)), \ ++ "rI" ((USItype)(y0)) \ ++ : "cc") ++ ++#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ ++ __asm__ ("subcc %r7,%8,%2\n\ ++ subxcc %r5,%6,%1\n\ ++ subx %r3,%4,%0" \ ++ : "=r" ((USItype)(r2)), \ ++ "=&r" ((USItype)(r1)), \ ++ "=&r" ((USItype)(r0)) \ ++ : "%rJ" ((USItype)(x2)), \ ++ "rI" ((USItype)(y2)), \ ++ "%rJ" ((USItype)(x1)), \ ++ "rI" ((USItype)(y1)), \ ++ "%rJ" ((USItype)(x0)), \ ++ "rI" ((USItype)(y0)) \ ++ : "cc") ++ ++#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ ++ do { \ ++ /* We need to fool gcc, as we need to pass more than 10 \ ++ input/outputs. */ \ ++ register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2"); \ ++ __asm__ __volatile__ ("\ ++ addcc %r8,%9,%1\n\ ++ addxcc %r6,%7,%0\n\ ++ addxcc %r4,%5,%%g2\n\ ++ addx %r2,%3,%%g1" \ ++ : "=&r" ((USItype)(r1)), \ ++ "=&r" ((USItype)(r0)) \ ++ : "%rJ" ((USItype)(x3)), \ ++ "rI" ((USItype)(y3)), \ ++ "%rJ" ((USItype)(x2)), \ ++ "rI" ((USItype)(y2)), \ ++ "%rJ" ((USItype)(x1)), \ ++ "rI" ((USItype)(y1)), \ ++ "%rJ" ((USItype)(x0)), \ ++ "rI" ((USItype)(y0)) \ ++ : "cc", "g1", "g2"); \ ++ __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2)); \ ++ r3 = _t1; r2 = _t2; \ ++ } while (0) ++ ++#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ ++ do { \ ++ /* We need to fool gcc, as we need to pass more than 10 \ ++ input/outputs. */ \ ++ register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2"); \ ++ __asm__ __volatile__ ("\ ++ subcc %r8,%9,%1\n\ ++ subxcc %r6,%7,%0\n\ ++ subxcc %r4,%5,%%g2\n\ ++ subx %r2,%3,%%g1" \ ++ : "=&r" ((USItype)(r1)), \ ++ "=&r" ((USItype)(r0)) \ ++ : "%rJ" ((USItype)(x3)), \ ++ "rI" ((USItype)(y3)), \ ++ "%rJ" ((USItype)(x2)), \ ++ "rI" ((USItype)(y2)), \ ++ "%rJ" ((USItype)(x1)), \ ++ "rI" ((USItype)(y1)), \ ++ "%rJ" ((USItype)(x0)), \ ++ "rI" ((USItype)(y0)) \ ++ : "cc", "g1", "g2"); \ ++ __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2)); \ ++ r3 = _t1; r2 = _t2; \ ++ } while (0) ++ ++#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0) ++ ++#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0) ++ ++#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \ ++ __asm__ ("addcc %3,%4,%3\n\ ++ addxcc %2,%%g0,%2\n\ ++ addxcc %1,%%g0,%1\n\ ++ addx %0,%%g0,%0" \ ++ : "=&r" ((USItype)(x3)), \ ++ "=&r" ((USItype)(x2)), \ ++ "=&r" ((USItype)(x1)), \ ++ "=&r" ((USItype)(x0)) \ ++ : "rI" ((USItype)(i)), \ ++ "0" ((USItype)(x3)), \ ++ "1" ((USItype)(x2)), \ ++ "2" ((USItype)(x1)), \ ++ "3" ((USItype)(x0)) \ ++ : "cc") ++ ++/* Obtain the current rounding mode. */ ++#ifndef FP_ROUNDMODE ++#define FP_ROUNDMODE ((_fcw >> 30) & 0x3) ++#endif ++ ++/* Exception flags. */ ++#define FP_EX_INVALID (1 << 4) ++#define FP_EX_OVERFLOW (1 << 3) ++#define FP_EX_UNDERFLOW (1 << 2) ++#define FP_EX_DIVZERO (1 << 1) ++#define FP_EX_INEXACT (1 << 0) ++ ++#define _FP_DECL_EX fpu_control_t _fcw ++ ++#define FP_INIT_ROUNDMODE \ ++do { \ ++ _FPU_GETCW(_fcw); \ ++} while (0) ++ ++/* Simulate exceptions using double arithmetics. */ ++extern double ___Q_simulate_exceptions(int exc); ++ ++#define FP_HANDLE_EXCEPTIONS \ ++do { \ ++ if (!_fex) \ ++ { \ ++ /* This is the common case, so we do it inline. \ ++ * We need to clear cexc bits if any. \ ++ */ \ ++ extern unsigned long long ___Q_numbers[]; \ ++ __asm__ __volatile__("\ ++ ldd [%0], %%f30\n\ ++ faddd %%f30, %%f30, %%f30\ ++ " : : "r" (___Q_numbers) : "f30"); \ ++ } \ ++ else \ ++ ___Q_simulate_exceptions (_fex); \ ++} while (0) +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/single.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/single.h +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/single.h 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/single.h 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,151 @@ ++/* Software floating-point emulation. ++ Definitions for IEEE Single Precision. ++ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com), ++ Jakub Jelinek (jj@ultra.linux.cz), ++ David S. Miller (davem@redhat.com) and ++ Peter Maydell (pmaydell@chiark.greenend.org.uk). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ In addition to the permissions in the GNU Lesser General Public ++ License, the Free Software Foundation gives you unlimited ++ permission to link the compiled version of this file into ++ combinations with other programs, and to distribute those ++ combinations without any restriction coming from the use of this ++ file. (The Lesser General Public License restrictions do apply in ++ other respects; for example, they cover modification of the file, ++ and distribution when not linked into a combine executable.) ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#if _FP_W_TYPE_SIZE < 32 ++#error "Here's a nickel kid. Go buy yourself a real computer." ++#endif ++ ++#define _FP_FRACTBITS_S _FP_W_TYPE_SIZE ++ ++#define _FP_FRACBITS_S 24 ++#define _FP_FRACXBITS_S (_FP_FRACTBITS_S - _FP_FRACBITS_S) ++#define _FP_WFRACBITS_S (_FP_WORKBITS + _FP_FRACBITS_S) ++#define _FP_WFRACXBITS_S (_FP_FRACTBITS_S - _FP_WFRACBITS_S) ++#define _FP_EXPBITS_S 8 ++#define _FP_EXPBIAS_S 127 ++#define _FP_EXPMAX_S 255 ++#define _FP_QNANBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2)) ++#define _FP_QNANBIT_SH_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2+_FP_WORKBITS)) ++#define _FP_IMPLBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1)) ++#define _FP_IMPLBIT_SH_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1+_FP_WORKBITS)) ++#define _FP_OVERFLOW_S ((_FP_W_TYPE)1 << (_FP_WFRACBITS_S)) ++ ++/* The implementation of _FP_MUL_MEAT_S and _FP_DIV_MEAT_S should be ++ chosen by the target machine. */ ++ ++typedef float SFtype __attribute__((mode(SF))); ++ ++union _FP_UNION_S ++{ ++ SFtype flt; ++ struct { ++#if __BYTE_ORDER == __BIG_ENDIAN ++ unsigned sign : 1; ++ unsigned exp : _FP_EXPBITS_S; ++ unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0); ++#else ++ unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0); ++ unsigned exp : _FP_EXPBITS_S; ++ unsigned sign : 1; ++#endif ++ } bits __attribute__((packed)); ++}; ++ ++#define FP_DECL_S(X) _FP_DECL(1,X) ++#define FP_UNPACK_RAW_S(X,val) _FP_UNPACK_RAW_1(S,X,val) ++#define FP_UNPACK_RAW_SP(X,val) _FP_UNPACK_RAW_1_P(S,X,val) ++#define FP_PACK_RAW_S(val,X) _FP_PACK_RAW_1(S,val,X) ++#define FP_PACK_RAW_SP(val,X) \ ++ do { \ ++ if (!FP_INHIBIT_RESULTS) \ ++ _FP_PACK_RAW_1_P(S,val,X); \ ++ } while (0) ++ ++#define FP_UNPACK_S(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_1(S,X,val); \ ++ _FP_UNPACK_CANONICAL(S,1,X); \ ++ } while (0) ++ ++#define FP_UNPACK_SP(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_1_P(S,X,val); \ ++ _FP_UNPACK_CANONICAL(S,1,X); \ ++ } while (0) ++ ++#define FP_UNPACK_SEMIRAW_S(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_1(S,X,val); \ ++ _FP_UNPACK_SEMIRAW(S,1,X); \ ++ } while (0) ++ ++#define FP_UNPACK_SEMIRAW_SP(X,val) \ ++ do { \ ++ _FP_UNPACK_RAW_1_P(S,X,val); \ ++ _FP_UNPACK_SEMIRAW(S,1,X); \ ++ } while (0) ++ ++#define FP_PACK_S(val,X) \ ++ do { \ ++ _FP_PACK_CANONICAL(S,1,X); \ ++ _FP_PACK_RAW_1(S,val,X); \ ++ } while (0) ++ ++#define FP_PACK_SP(val,X) \ ++ do { \ ++ _FP_PACK_CANONICAL(S,1,X); \ ++ if (!FP_INHIBIT_RESULTS) \ ++ _FP_PACK_RAW_1_P(S,val,X); \ ++ } while (0) ++ ++#define FP_PACK_SEMIRAW_S(val,X) \ ++ do { \ ++ _FP_PACK_SEMIRAW(S,1,X); \ ++ _FP_PACK_RAW_1(S,val,X); \ ++ } while (0) ++ ++#define FP_PACK_SEMIRAW_SP(val,X) \ ++ do { \ ++ _FP_PACK_SEMIRAW(S,1,X); \ ++ if (!FP_INHIBIT_RESULTS) \ ++ _FP_PACK_RAW_1_P(S,val,X); \ ++ } while (0) ++ ++#define FP_ISSIGNAN_S(X) _FP_ISSIGNAN(S,1,X) ++#define FP_NEG_S(R,X) _FP_NEG(S,1,R,X) ++#define FP_ADD_S(R,X,Y) _FP_ADD(S,1,R,X,Y) ++#define FP_SUB_S(R,X,Y) _FP_SUB(S,1,R,X,Y) ++#define FP_MUL_S(R,X,Y) _FP_MUL(S,1,R,X,Y) ++#define FP_DIV_S(R,X,Y) _FP_DIV(S,1,R,X,Y) ++#define FP_SQRT_S(R,X) _FP_SQRT(S,1,R,X) ++#define _FP_SQRT_MEAT_S(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q) ++ ++#define FP_CMP_S(r,X,Y,un) _FP_CMP(S,1,r,X,Y,un) ++#define FP_CMP_EQ_S(r,X,Y) _FP_CMP_EQ(S,1,r,X,Y) ++#define FP_CMP_UNORD_S(r,X,Y) _FP_CMP_UNORD(S,1,r,X,Y) ++ ++#define FP_TO_INT_S(r,X,rsz,rsg) _FP_TO_INT(S,1,r,X,rsz,rsg) ++#define FP_FROM_INT_S(X,r,rs,rt) _FP_FROM_INT(S,1,X,r,rs,rt) ++ ++#define _FP_FRAC_HIGH_S(X) _FP_FRAC_HIGH_1(X) ++#define _FP_FRAC_HIGH_RAW_S(X) _FP_FRAC_HIGH_1(X) +diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/soft-fp.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/soft-fp.h +--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/soft-fp.h 1970-01-01 01:00:00.000000000 +0100 ++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/soft-fp.h 2010-10-14 14:05:37.000000000 +0200 +@@ -0,0 +1,205 @@ ++/* Software floating-point emulation. ++ Copyright (C) 1997,1998,1999,2000,2002,2003,2005,2006,2007 ++ Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Richard Henderson (rth@cygnus.com), ++ Jakub Jelinek (jj@ultra.linux.cz), ++ David S. Miller (davem@redhat.com) and ++ Peter Maydell (pmaydell@chiark.greenend.org.uk). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ In addition to the permissions in the GNU Lesser General Public ++ License, the Free Software Foundation gives you unlimited ++ permission to link the compiled version of this file into ++ combinations with other programs, and to distribute those ++ combinations without any restriction coming from the use of this ++ file. (The Lesser General Public License restrictions do apply in ++ other respects; for example, they cover modification of the file, ++ and distribution when not linked into a combine executable.) ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#ifndef SOFT_FP_H ++#define SOFT_FP_H ++ ++#include "sfp-machine.h" ++ ++/* Allow sfp-machine to have its own byte order definitions. */ ++#ifndef __BYTE_ORDER ++#ifdef _LIBC ++#include ++#else ++#error "endianness not defined by sfp-machine.h" ++#endif ++#endif ++ ++#define _FP_WORKBITS 3 ++#define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3) ++#define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2) ++#define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1) ++#define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0) ++ ++#ifndef FP_RND_NEAREST ++# define FP_RND_NEAREST 0 ++# define FP_RND_ZERO 1 ++# define FP_RND_PINF 2 ++# define FP_RND_MINF 3 ++#endif ++#ifndef FP_ROUNDMODE ++# define FP_ROUNDMODE FP_RND_NEAREST ++#endif ++ ++/* By default don't care about exceptions. */ ++#ifndef FP_EX_INVALID ++#define FP_EX_INVALID 0 ++#endif ++#ifndef FP_EX_OVERFLOW ++#define FP_EX_OVERFLOW 0 ++#endif ++#ifndef FP_EX_UNDERFLOW ++#define FP_EX_UNDERFLOW 0 ++#endif ++#ifndef FP_EX_DIVZERO ++#define FP_EX_DIVZERO 0 ++#endif ++#ifndef FP_EX_INEXACT ++#define FP_EX_INEXACT 0 ++#endif ++#ifndef FP_EX_DENORM ++#define FP_EX_DENORM 0 ++#endif ++ ++#ifdef _FP_DECL_EX ++#define FP_DECL_EX \ ++ int _fex = 0; \ ++ _FP_DECL_EX ++#else ++#define FP_DECL_EX int _fex = 0 ++#endif ++ ++#ifndef FP_INIT_ROUNDMODE ++#define FP_INIT_ROUNDMODE do {} while (0) ++#endif ++ ++#ifndef FP_HANDLE_EXCEPTIONS ++#define FP_HANDLE_EXCEPTIONS do {} while (0) ++#endif ++ ++#ifndef FP_INHIBIT_RESULTS ++/* By default we write the results always. ++ * sfp-machine may override this and e.g. ++ * check if some exceptions are unmasked ++ * and inhibit it in such a case. ++ */ ++#define FP_INHIBIT_RESULTS 0 ++#endif ++ ++#define FP_SET_EXCEPTION(ex) \ ++ _fex |= (ex) ++ ++#define FP_UNSET_EXCEPTION(ex) \ ++ _fex &= ~(ex) ++ ++#define FP_CLEAR_EXCEPTIONS \ ++ _fex = 0 ++ ++#define _FP_ROUND_NEAREST(wc, X) \ ++do { \ ++ if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND) \ ++ _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \ ++} while (0) ++ ++#define _FP_ROUND_ZERO(wc, X) (void)0 ++ ++#define _FP_ROUND_PINF(wc, X) \ ++do { \ ++ if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ ++ _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ ++} while (0) ++ ++#define _FP_ROUND_MINF(wc, X) \ ++do { \ ++ if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ ++ _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ ++} while (0) ++ ++#define _FP_ROUND(wc, X) \ ++do { \ ++ if (_FP_FRAC_LOW_##wc(X) & 7) \ ++ FP_SET_EXCEPTION(FP_EX_INEXACT); \ ++ switch (FP_ROUNDMODE) \ ++ { \ ++ case FP_RND_NEAREST: \ ++ _FP_ROUND_NEAREST(wc,X); \ ++ break; \ ++ case FP_RND_ZERO: \ ++ _FP_ROUND_ZERO(wc,X); \ ++ break; \ ++ case FP_RND_PINF: \ ++ _FP_ROUND_PINF(wc,X); \ ++ break; \ ++ case FP_RND_MINF: \ ++ _FP_ROUND_MINF(wc,X); \ ++ break; \ ++ } \ ++} while (0) ++ ++#define FP_CLS_NORMAL 0 ++#define FP_CLS_ZERO 1 ++#define FP_CLS_INF 2 ++#define FP_CLS_NAN 3 ++ ++#define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y)) ++ ++#include "op-1.h" ++#include "op-2.h" ++#include "op-4.h" ++#include "op-8.h" ++#include "op-common.h" ++ ++/* Sigh. Silly things longlong.h needs. */ ++#define UWtype _FP_W_TYPE ++#define W_TYPE_SIZE _FP_W_TYPE_SIZE ++ ++typedef int QItype __attribute__((mode(QI))); ++typedef int SItype __attribute__((mode(SI))); ++typedef int DItype __attribute__((mode(DI))); ++typedef unsigned int UQItype __attribute__((mode(QI))); ++typedef unsigned int USItype __attribute__((mode(SI))); ++typedef unsigned int UDItype __attribute__((mode(DI))); ++#if _FP_W_TYPE_SIZE == 32 ++typedef unsigned int UHWtype __attribute__((mode(HI))); ++#elif _FP_W_TYPE_SIZE == 64 ++typedef USItype UHWtype; ++#endif ++ ++#ifndef CMPtype ++#define CMPtype int ++#endif ++ ++#define SI_BITS (__CHAR_BIT__ * (int)sizeof(SItype)) ++#define DI_BITS (__CHAR_BIT__ * (int)sizeof(DItype)) ++ ++#ifndef umul_ppmm ++#include "longlong.h" ++#endif ++ ++#ifdef _LIBC ++#include ++#else ++extern void abort (void); ++#endif ++ ++#endif diff --git a/toolchain/uClibc/uClibc-0.9.31.1-workaround-GCC-PR32219.patch b/toolchain/uClibc/uClibc-0.9.31.1-workaround-GCC-PR32219.patch new file mode 100644 index 0000000000..242a5264b8 --- /dev/null +++ b/toolchain/uClibc/uClibc-0.9.31.1-workaround-GCC-PR32219.patch @@ -0,0 +1,57 @@ +From 2e53dd645d5348f207cec7f8595969dc566c5a55 Mon Sep 17 00:00:00 2001 +From: Denys Vlasenko +Date: Mon, 17 May 2010 15:56:19 +0200 +Subject: [PATCH] workaround GCC PR32219 + +we ended up calling 0 +Fixes bug #1033 + +Signed-off-by: Denys Vlasenko +Signed-off-by: Bernhard Reutner-Fischer +--- + libc/misc/internals/__uClibc_main.c | 15 +++++++++++++-- + 1 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c +index f9e1244..4ee4443 100644 +--- a/libc/misc/internals/__uClibc_main.c ++++ b/libc/misc/internals/__uClibc_main.c +@@ -105,6 +105,17 @@ _pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer *__buffer, + + #endif /* !SHARED */ + ++/* Defeat compiler optimization which assumes function addresses are never NULL */ ++static __always_inline int not_null_ptr(const void *p) ++{ ++ const void *q; ++ __asm__ ("" ++ : "=r" (q) /* output */ ++ : "0" (p) /* input */ ++ ); ++ return q != 0; ++} ++ + /* + * Prototypes. + */ +@@ -254,7 +265,7 @@ void __uClibc_init(void) + + #ifdef __UCLIBC_HAS_LOCALE__ + /* Initialize the global locale structure. */ +- if (likely(_locale_init!=NULL)) ++ if (likely(not_null_ptr(_locale_init))) + _locale_init(); + #endif + +@@ -264,7 +275,7 @@ void __uClibc_init(void) + * Thus we get a nice size savings because the stdio functions + * won't be pulled into the final static binary unless used. + */ +- if (likely(_stdio_init != NULL)) ++ if (likely(not_null_ptr(_stdio_init))) + _stdio_init(); + + } +-- +1.7.1 +