summary refs log tree commit diff
path: root/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
diff options
context:
space:
mode:
Diffstat (limited to 'linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h')
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h30
1 files changed, 29 insertions, 1 deletions
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
index 2f7c546a4c..865da8e8ca 100644
--- a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
+++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
@@ -37,6 +37,7 @@
     stwu 1,-48(1);							\
     mflr 9;								\
     stw 9,52(1);							\
+    CGOTSETUP;								\
     DOCARGS_##args;	/* save syscall args around CENABLE.  */	\
     CENABLE;								\
     stw 3,16(1);	/* store CENABLE return value (MASK).  */	\
@@ -50,6 +51,7 @@
     lwz 4,52(1);							\
     lwz 0,12(1);	/* restore CR/R3. */				\
     lwz 3,8(1);								\
+    CGOTRESTORE;							\
     mtlr 4;								\
     mtcr 0;								\
     addi 1,1,48;
@@ -75,6 +77,9 @@
 # define DOCARGS_6	stw 8,40(1); DOCARGS_5
 # define UNDOCARGS_6	lwz 8,40(1); UNDOCARGS_5
 
+# define CGOTSETUP
+# define CGOTRESTORE
+
 # ifdef IS_IN_libpthread
 #  define CENABLE	bl __pthread_enable_asynccancel@local
 #  define CDISABLE	bl __pthread_disable_asynccancel@local
@@ -84,6 +89,18 @@
 # else
 #  define CENABLE	bl JUMPTARGET(__librt_enable_asynccancel)
 #  define CDISABLE	bl JUMPTARGET(__librt_disable_asynccancel)
+#  if defined HAVE_AS_REL16 && defined PIC
+#   undef CGOTSETUP
+#   define CGOTSETUP							\
+    bcl 20,31,1f;							\
+ 1: stw 30,44(1);							\
+    mflr 30;								\
+    addis 30,30,_GLOBAL_OFFSET_TABLE-1b@ha;				\
+    addi 30,30,_GLOBAL_OFFSET_TABLE-1b@l
+#   undef CGOTRESTORE
+#   define CGOTRESTORE							\
+    lwz 30,44(1)
+#  endif
 # endif
 
 # ifdef HAVE_TLS_SUPPORT
@@ -111,7 +128,17 @@ extern int __local_multiple_threads attribute_hidden;
   lwz 10,__local_multiple_threads@l(10);				\
   cmpwi 10,0
 #   else
-#    define SINGLE_THREAD_P						\
+#    ifdef HAVE_ASM_PPC_REL16
+#     define SINGLE_THREAD_P						\
+  mflr 9;								\
+  bcl 20,31,1f;								\
+1:mflr 10;								\
+  addis 10,10,__local_multiple_threads-1b@ha;				\
+  lwz 10,__local_multiple_threads-1b@l(10);				\
+  mtlr 9;								\
+  cmpwi 10,0
+#    else
+#     define SINGLE_THREAD_P						\
   mflr 9;								\
   bl _GLOBAL_OFFSET_TABLE_@local-4;					\
   mflr 10;								\
@@ -119,6 +146,7 @@ extern int __local_multiple_threads attribute_hidden;
   lwz 10,__local_multiple_threads@got(10);				\
   lwz 10,0(10);								\
   cmpwi 10,0
+#    endif
 #   endif
 #  endif
 # endif