summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/mips/pthread_arch.h3
-rw-r--r--arch/powerpc/bits/fenv.h2
-rw-r--r--arch/powerpc/reloc.h2
-rwxr-xr-xconfigure4
-rw-r--r--include/stdlib.h1
-rw-r--r--src/fenv/powerpc/fenv-sf.c2
-rw-r--r--src/fenv/powerpc/fenv.S2
-rw-r--r--src/include/stdlib.h1
-rw-r--r--src/math/powerpc/fabs.c2
-rw-r--r--src/math/powerpc/fabsf.c2
-rw-r--r--src/math/powerpc/fma.c2
-rw-r--r--src/math/powerpc/fmaf.c2
-rw-r--r--src/setjmp/powerpc/longjmp.S32
-rw-r--r--src/setjmp/powerpc/setjmp.S32
-rw-r--r--src/signal/block.c4
-rw-r--r--src/stdio/getdelim.c8
-rw-r--r--src/stdlib/qsort.c37
-rw-r--r--src/stdlib/qsort_nr.c14
-rw-r--r--src/thread/pthread_getname_np.c2
19 files changed, 116 insertions, 38 deletions
diff --git a/arch/mips/pthread_arch.h b/arch/mips/pthread_arch.h
index c45347ab..376b7741 100644
--- a/arch/mips/pthread_arch.h
+++ b/arch/mips/pthread_arch.h
@@ -1,10 +1,9 @@
static inline uintptr_t __get_tp()
{
-#if __mips_isa_rev < 2
register uintptr_t tp __asm__("$3");
+#if __mips_isa_rev < 2
__asm__ (".word 0x7c03e83b" : "=r" (tp) );
#else
- uintptr_t tp;
__asm__ ("rdhwr %0, $29" : "=r" (tp) );
#endif
return tp;
diff --git a/arch/powerpc/bits/fenv.h b/arch/powerpc/bits/fenv.h
index c5a3e5c5..5b15c69a 100644
--- a/arch/powerpc/bits/fenv.h
+++ b/arch/powerpc/bits/fenv.h
@@ -1,4 +1,4 @@
-#ifdef _SOFT_FLOAT
+#if defined(_SOFT_FLOAT) || defined(__NO_FPRS__)
#define FE_ALL_EXCEPT 0
#define FE_TONEAREST 0
#else
diff --git a/arch/powerpc/reloc.h b/arch/powerpc/reloc.h
index 527b6b7c..fdfbf827 100644
--- a/arch/powerpc/reloc.h
+++ b/arch/powerpc/reloc.h
@@ -1,4 +1,4 @@
-#ifdef _SOFT_FLOAT
+#if defined(_SOFT_FLOAT) || defined(__NO_FPRS__)
#define FP_SUFFIX "-sf"
#else
#define FP_SUFFIX ""
diff --git a/configure b/configure
index a5231a0e..e1aefed7 100755
--- a/configure
+++ b/configure
@@ -671,9 +671,7 @@ trycppif __mips_soft_float "$t" && SUBARCH=${SUBARCH}-sf
fi
if test "$ARCH" = "powerpc" ; then
-trycppif "__NO_FPRS__ && !_SOFT_FLOAT" "$t" && fail \
- "$0: error: compiler's floating point configuration is unsupported"
-trycppif _SOFT_FLOAT "$t" && SUBARCH=${SUBARCH}-sf
+trycppif "_SOFT_FLOAT || __NO_FPRS__" "$t" && SUBARCH=${SUBARCH}-sf
printf "checking whether compiler can use 'd' constraint in asm... "
echo 'double f(double x) { __asm__ ("fabs %0, %1" : "=d"(x) : "d"(x)); return x; }' > "$tmpc"
if $CC $CFLAGS_C99FSE $CPPFLAGS $CFLAGS -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
diff --git a/include/stdlib.h b/include/stdlib.h
index b54a051f..7af86e3b 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -146,6 +146,7 @@ int clearenv(void);
#define WCOREDUMP(s) ((s) & 0x80)
#define WIFCONTINUED(s) ((s) == 0xffff)
void *reallocarray (void *, size_t, size_t);
+void qsort_r (void *, size_t, size_t, int (*)(const void *, const void *, void *), void *);
#endif
#ifdef _GNU_SOURCE
diff --git a/src/fenv/powerpc/fenv-sf.c b/src/fenv/powerpc/fenv-sf.c
index 85bef40f..d4248f26 100644
--- a/src/fenv/powerpc/fenv-sf.c
+++ b/src/fenv/powerpc/fenv-sf.c
@@ -1,3 +1,3 @@
-#ifdef _SOFT_FLOAT
+#if defined(_SOFT_FLOAT) || defined(__NO_FPRS__)
#include "../fenv.c"
#endif
diff --git a/src/fenv/powerpc/fenv.S b/src/fenv/powerpc/fenv.S
index 22cea216..55055d0b 100644
--- a/src/fenv/powerpc/fenv.S
+++ b/src/fenv/powerpc/fenv.S
@@ -1,4 +1,4 @@
-#ifndef _SOFT_FLOAT
+#if !defined(_SOFT_FLOAT) && !defined(__NO_FPRS__)
.global feclearexcept
.type feclearexcept,@function
feclearexcept:
diff --git a/src/include/stdlib.h b/src/include/stdlib.h
index e9da2015..812b04de 100644
--- a/src/include/stdlib.h
+++ b/src/include/stdlib.h
@@ -8,6 +8,7 @@ hidden void __env_rm_add(char *, char *);
hidden int __mkostemps(char *, int, int);
hidden int __ptsname_r(int, char *, size_t);
hidden char *__randname(char *);
+hidden void __qsort_r (void *, size_t, size_t, int (*)(const void *, const void *, void *), void *);
hidden void *__libc_malloc(size_t);
hidden void *__libc_malloc_impl(size_t);
diff --git a/src/math/powerpc/fabs.c b/src/math/powerpc/fabs.c
index 0efc21ef..9453a3aa 100644
--- a/src/math/powerpc/fabs.c
+++ b/src/math/powerpc/fabs.c
@@ -1,6 +1,6 @@
#include <math.h>
-#if defined(_SOFT_FLOAT) || defined(BROKEN_PPC_D_ASM)
+#if defined(_SOFT_FLOAT) || defined(__NO_FPRS__) || defined(BROKEN_PPC_D_ASM)
#include "../fabs.c"
diff --git a/src/math/powerpc/fabsf.c b/src/math/powerpc/fabsf.c
index d88b5911..2e9da588 100644
--- a/src/math/powerpc/fabsf.c
+++ b/src/math/powerpc/fabsf.c
@@ -1,6 +1,6 @@
#include <math.h>
-#ifdef _SOFT_FLOAT
+#if defined(_SOFT_FLOAT) || defined(__NO_FPRS__)
#include "../fabsf.c"
diff --git a/src/math/powerpc/fma.c b/src/math/powerpc/fma.c
index 135c9903..0eb2ba1e 100644
--- a/src/math/powerpc/fma.c
+++ b/src/math/powerpc/fma.c
@@ -1,6 +1,6 @@
#include <math.h>
-#if defined(_SOFT_FLOAT) || defined(BROKEN_PPC_D_ASM)
+#if defined(_SOFT_FLOAT) || defined(__NO_FPRS__) || defined(BROKEN_PPC_D_ASM)
#include "../fma.c"
diff --git a/src/math/powerpc/fmaf.c b/src/math/powerpc/fmaf.c
index a99a2a3b..dc1a749d 100644
--- a/src/math/powerpc/fmaf.c
+++ b/src/math/powerpc/fmaf.c
@@ -1,6 +1,6 @@
#include <math.h>
-#ifdef _SOFT_FLOAT
+#if defined(_SOFT_FLOAT) || defined(__NO_FPRS__)
#include "../fmaf.c"
diff --git a/src/setjmp/powerpc/longjmp.S b/src/setjmp/powerpc/longjmp.S
index e598bd05..34aecb4c 100644
--- a/src/setjmp/powerpc/longjmp.S
+++ b/src/setjmp/powerpc/longjmp.S
@@ -37,7 +37,37 @@ longjmp:
lwz 29, 72(3)
lwz 30, 76(3)
lwz 31, 80(3)
-#ifndef _SOFT_FLOAT
+#if defined(_SOFT_FLOAT) || defined(__NO_FPRS__)
+ mflr 0
+ bl 1f
+ .hidden __hwcap
+ .long __hwcap-.
+1: mflr 4
+ lwz 5, 0(4)
+ add 4, 4, 5
+ andis. 4, 4, 0x80
+ beq 1f
+ .long 0x11c35b01 /* evldd 14,88(3) */
+ .long 0x11e36301 /* ... */
+ .long 0x12036b01
+ .long 0x12237301
+ .long 0x12437b01
+ .long 0x12638301
+ .long 0x12838b01
+ .long 0x12a39301
+ .long 0x12c39b01
+ .long 0x12e3a301
+ .long 0x1303ab01
+ .long 0x1323b301
+ .long 0x1343bb01
+ .long 0x1363c301
+ .long 0x1383cb01
+ .long 0x13a3d301
+ .long 0x13c3db01
+ .long 0x13e3e301 /* evldd 31,224(3) */
+ .long 0x11a3eb01 /* evldd 13,232(3) */
+1: mtlr 0
+#else
lfd 14,88(3)
lfd 15,96(3)
lfd 16,104(3)
diff --git a/src/setjmp/powerpc/setjmp.S b/src/setjmp/powerpc/setjmp.S
index cd91a207..413e6a81 100644
--- a/src/setjmp/powerpc/setjmp.S
+++ b/src/setjmp/powerpc/setjmp.S
@@ -37,7 +37,37 @@ setjmp:
stw 29, 72(3)
stw 30, 76(3)
stw 31, 80(3)
-#ifndef _SOFT_FLOAT
+#if defined(_SOFT_FLOAT) || defined(__NO_FPRS__)
+ mflr 0
+ bl 1f
+ .hidden __hwcap
+ .long __hwcap-.
+1: mflr 4
+ lwz 5, 0(4)
+ add 4, 4, 5
+ andis. 4, 4, 0x80
+ beq 1f
+ .long 0x11c35b21 /* evstdd 14,88(3) */
+ .long 0x11e36321 /* ... */
+ .long 0x12036b21
+ .long 0x12237321
+ .long 0x12437b21
+ .long 0x12638321
+ .long 0x12838b21
+ .long 0x12a39321
+ .long 0x12c39b21
+ .long 0x12e3a321
+ .long 0x1303ab21
+ .long 0x1323b321
+ .long 0x1343bb21
+ .long 0x1363c321
+ .long 0x1383cb21
+ .long 0x13a3d321
+ .long 0x13c3db21
+ .long 0x13e3e321 /* evstdd 31,224(3) */
+ .long 0x11a3eb21 /* evstdd 13,232(3) */
+1: mtlr 0
+#else
stfd 14,88(3)
stfd 15,96(3)
stfd 16,104(3)
diff --git a/src/signal/block.c b/src/signal/block.c
index d7f61001..cc8698f0 100644
--- a/src/signal/block.c
+++ b/src/signal/block.c
@@ -3,9 +3,9 @@
#include <signal.h>
static const unsigned long all_mask[] = {
-#if ULONG_MAX == 0xffffffff && _NSIG == 129
+#if ULONG_MAX == 0xffffffff && _NSIG > 65
-1UL, -1UL, -1UL, -1UL
-#elif ULONG_MAX == 0xffffffff
+#elif ULONG_MAX == 0xffffffff || _NSIG > 65
-1UL, -1UL
#else
-1UL
diff --git a/src/stdio/getdelim.c b/src/stdio/getdelim.c
index d2f5b15a..df114441 100644
--- a/src/stdio/getdelim.c
+++ b/src/stdio/getdelim.c
@@ -55,9 +55,11 @@ ssize_t getdelim(char **restrict s, size_t *restrict n, int delim, FILE *restric
*s = tmp;
*n = m;
}
- memcpy(*s+i, f->rpos, k);
- f->rpos += k;
- i += k;
+ if (k) {
+ memcpy(*s+i, f->rpos, k);
+ f->rpos += k;
+ i += k;
+ }
if (z) break;
if ((c = getc_unlocked(f)) == EOF) {
if (!i || !feof(f)) {
diff --git a/src/stdlib/qsort.c b/src/stdlib/qsort.c
index da58fd31..314ddc29 100644
--- a/src/stdlib/qsort.c
+++ b/src/stdlib/qsort.c
@@ -24,6 +24,7 @@
/* Smoothsort, an adaptive variant of Heapsort. Memory usage: O(1).
Run time: Worst case O(n log n), close to O(n) in the mostly-sorted case. */
+#define _BSD_SOURCE
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -31,7 +32,7 @@
#include "atomic.h"
#define ntz(x) a_ctz_l((x))
-typedef int (*cmpfun)(const void *, const void *);
+typedef int (*cmpfun)(const void *, const void *, void *);
static inline int pntz(size_t p[2]) {
int r = ntz(p[0] - 1);
@@ -88,7 +89,7 @@ static inline void shr(size_t p[2], int n)
p[1] >>= n;
}
-static void sift(unsigned char *head, size_t width, cmpfun cmp, int pshift, size_t lp[])
+static void sift(unsigned char *head, size_t width, cmpfun cmp, void *arg, int pshift, size_t lp[])
{
unsigned char *rt, *lf;
unsigned char *ar[14 * sizeof(size_t) + 1];
@@ -99,10 +100,10 @@ static void sift(unsigned char *head, size_t width, cmpfun cmp, int pshift, size
rt = head - width;
lf = head - width - lp[pshift - 2];
- if((*cmp)(ar[0], lf) >= 0 && (*cmp)(ar[0], rt) >= 0) {
+ if(cmp(ar[0], lf, arg) >= 0 && cmp(ar[0], rt, arg) >= 0) {
break;
}
- if((*cmp)(lf, rt) >= 0) {
+ if(cmp(lf, rt, arg) >= 0) {
ar[i++] = lf;
head = lf;
pshift -= 1;
@@ -115,7 +116,7 @@ static void sift(unsigned char *head, size_t width, cmpfun cmp, int pshift, size
cycle(width, ar, i);
}
-static void trinkle(unsigned char *head, size_t width, cmpfun cmp, size_t pp[2], int pshift, int trusty, size_t lp[])
+static void trinkle(unsigned char *head, size_t width, cmpfun cmp, void *arg, size_t pp[2], int pshift, int trusty, size_t lp[])
{
unsigned char *stepson,
*rt, *lf;
@@ -130,13 +131,13 @@ static void trinkle(unsigned char *head, size_t width, cmpfun cmp, size_t pp[2],
ar[0] = head;
while(p[0] != 1 || p[1] != 0) {
stepson = head - lp[pshift];
- if((*cmp)(stepson, ar[0]) <= 0) {
+ if(cmp(stepson, ar[0], arg) <= 0) {
break;
}
if(!trusty && pshift > 1) {
rt = head - width;
lf = head - width - lp[pshift - 2];
- if((*cmp)(rt, stepson) >= 0 || (*cmp)(lf, stepson) >= 0) {
+ if(cmp(rt, stepson, arg) >= 0 || cmp(lf, stepson, arg) >= 0) {
break;
}
}
@@ -150,11 +151,11 @@ static void trinkle(unsigned char *head, size_t width, cmpfun cmp, size_t pp[2],
}
if(!trusty) {
cycle(width, ar, i);
- sift(head, width, cmp, pshift, lp);
+ sift(head, width, cmp, arg, pshift, lp);
}
}
-void qsort(void *base, size_t nel, size_t width, cmpfun cmp)
+void __qsort_r(void *base, size_t nel, size_t width, cmpfun cmp, void *arg)
{
size_t lp[12*sizeof(size_t)];
size_t i, size = width * nel;
@@ -173,16 +174,16 @@ void qsort(void *base, size_t nel, size_t width, cmpfun cmp)
while(head < high) {
if((p[0] & 3) == 3) {
- sift(head, width, cmp, pshift, lp);
+ sift(head, width, cmp, arg, pshift, lp);
shr(p, 2);
pshift += 2;
} else {
if(lp[pshift - 1] >= high - head) {
- trinkle(head, width, cmp, p, pshift, 0, lp);
+ trinkle(head, width, cmp, arg, p, pshift, 0, lp);
} else {
- sift(head, width, cmp, pshift, lp);
+ sift(head, width, cmp, arg, pshift, lp);
}
-
+
if(pshift == 1) {
shl(p, 1);
pshift = 0;
@@ -191,12 +192,12 @@ void qsort(void *base, size_t nel, size_t width, cmpfun cmp)
pshift = 1;
}
}
-
+
p[0] |= 1;
head += width;
}
- trinkle(head, width, cmp, p, pshift, 0, lp);
+ trinkle(head, width, cmp, arg, p, pshift, 0, lp);
while(pshift != 1 || p[0] != 1 || p[1] != 0) {
if(pshift <= 1) {
@@ -208,11 +209,13 @@ void qsort(void *base, size_t nel, size_t width, cmpfun cmp)
pshift -= 2;
p[0] ^= 7;
shr(p, 1);
- trinkle(head - lp[pshift] - width, width, cmp, p, pshift + 1, 1, lp);
+ trinkle(head - lp[pshift] - width, width, cmp, arg, p, pshift + 1, 1, lp);
shl(p, 1);
p[0] |= 1;
- trinkle(head - width, width, cmp, p, pshift, 1, lp);
+ trinkle(head - width, width, cmp, arg, p, pshift, 1, lp);
}
head -= width;
}
}
+
+weak_alias(__qsort_r, qsort_r);
diff --git a/src/stdlib/qsort_nr.c b/src/stdlib/qsort_nr.c
new file mode 100644
index 00000000..efe7ccec
--- /dev/null
+++ b/src/stdlib/qsort_nr.c
@@ -0,0 +1,14 @@
+#define _BSD_SOURCE
+#include <stdlib.h>
+
+typedef int (*cmpfun)(const void *, const void *);
+
+static int wrapper_cmp(const void *v1, const void *v2, void *cmp)
+{
+ return ((cmpfun)cmp)(v1, v2);
+}
+
+void qsort(void *base, size_t nel, size_t width, cmpfun cmp)
+{
+ __qsort_r(base, nel, width, wrapper_cmp, cmp);
+}
diff --git a/src/thread/pthread_getname_np.c b/src/thread/pthread_getname_np.c
index 48d1a294..85504e45 100644
--- a/src/thread/pthread_getname_np.c
+++ b/src/thread/pthread_getname_np.c
@@ -17,7 +17,7 @@ int pthread_getname_np(pthread_t thread, char *name, size_t len)
snprintf(f, sizeof f, "/proc/self/task/%d/comm", thread->tid);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
- if ((fd = open(f, O_RDONLY|O_CLOEXEC)) < 0 || (len = read(fd, name, len)) < 0) status = errno;
+ if ((fd = open(f, O_RDONLY|O_CLOEXEC)) < 0 || (len = read(fd, name, len)) == -1) status = errno;
else name[len-1] = 0; /* remove trailing new line only if successful */
if (fd >= 0) close(fd);
pthread_setcancelstate(cs, 0);