This is the mail archive of the mailing list for the newlib project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] SPU use a non-functional errno

Hi Jeff -

Not sure of the best way to handle this, please comment or apply, thanks!

Modify SPU to directly use errno, since it does not need reentrant code.
With this patch, any code using errno is 8 bytes smaller, plus there is no
function call.

More importantly, testing of the SPU optimized math function asin showed a
decrease in time of 16%, a simple test took 16.6 seconds, where without
the change it took 19.7 seconds. Similar gains are likely for other math
domain checks in the SPU optimized math code (they are already set up for
branchless compare and setting of errno, but the code has to always read
and set errno).

Alternatively, we could use:

	extern int errno;

That means we would have another 4 bytes (maybe 8 for alignment) for the
errno, and would need our own errno.c (keep __errno() for backwards
compatibility), but would otherwise be ok.

Or use:

	#define errno (_REENT->_errno)

Means an extra level of indirection, so an extra instruction everywhere,
still much better than a function call on SPU, but not ideal.

2008-03-27 Patrick Mansfield <>

	* libc/machine/spu/sys/errno.h: Define errno to  _reent_data._errno.
	* libc/reent/impure.c: Add SPU extern _reent_data.
	* spu/sbrk.c: Remove "extern int errno", use whatever is supplied
	  by sys/errno.h.

Index: quilt/libgloss/spu/sbrk.c
--- quilt.orig/libgloss/spu/sbrk.c
+++ quilt/libgloss/spu/sbrk.c
@@ -34,8 +34,6 @@ Author: Andreas Neukoetter (ti95neuk@de.
 #include <errno.h>
 #include <spu_intrinsics.h>
-extern int errno;
 extern caddr_t  _end;
 #define STACKSIZE 4096
Index: quilt/newlib/libc/machine/spu/sys/errno.h
--- quilt.orig/newlib/libc/machine/spu/sys/errno.h
+++ quilt/newlib/libc/machine/spu/sys/errno.h
@@ -19,10 +19,6 @@
    on which it is based, except values used or returned by syscalls must
    be those of the Linux ppc.  */
-/* errno is not a global variable, because that would make using it
-   non-reentrant.  Instead, its address is returned by the function
-   __errno.  */
 #ifndef _SYS_ERRNO_H_
 #ifdef __cplusplus
 extern "C" {
@@ -31,10 +27,8 @@ extern "C" {
 #include <sys/reent.h>
-#ifndef _REENT_ONLY
-#define errno (*__errno())
-extern int *__errno _PARAMS ((void));
+extern struct _reent _reent_data;
+#define errno (_reent_data._errno)
 /* Please don't use these variables directly.
    Use strerror instead. */
Index: quilt/newlib/libc/reent/impure.c
--- quilt.orig/newlib/libc/reent/impure.c
+++ quilt/newlib/libc/reent/impure.c
@@ -10,7 +10,9 @@
 static struct _reent __ATTRIBUTE_IMPURE_DATA__ impure_data = _REENT_INIT (impure_data);
-#ifdef __CYGWIN__
+#if defined(__SPU__)
+extern struct _reent _reent_data __attribute__ ((alias("impure_data")));
+#elif defined(__CYGWIN__)
 extern struct _reent reent_data __attribute__ ((alias("impure_data")));
 struct _reent *__ATTRIBUTE_IMPURE_PTR__ _impure_ptr = &impure_data;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]