Browse Source

microblaze: fix linuxthreads support

Got the working code from https://github.com/jdkoftinoff/mb-linux-msli/,
otherwise SIGILL while using linuxthreads.
Waldemar Brodkorb 8 years ago
parent
commit
0ff3c78828
1 changed files with 30 additions and 56 deletions
  1. 30 56
      libpthread/linuxthreads/sysdeps/microblaze/pt-machine.h

+ 30 - 56
libpthread/linuxthreads/sysdeps/microblaze/pt-machine.h

@@ -9,7 +9,6 @@
  * General Public License.  See the file COPYING.LIB in the main
  * directory of this archive for more details.
  *
- * Written by Miles Bader <miles@gnu.org>
  */
 
 #ifndef _PT_MACHINE_H
@@ -18,12 +17,9 @@
 #include <features.h>
 
 #ifndef PT_EI
-# define PT_EI extern inline
+# define PT_EI __extern_always_inline
 #endif
 
-extern long int testandset (int *spinlock);
-extern int __compare_and_swap (long *ptr, long old, long new);
-
 /* Get some notion of the current stack.  Need not be exactly the top
    of the stack, just something somewhere in the current frame.  */
 #define CURRENT_STACK_FRAME  __stack_pointer
@@ -31,76 +27,54 @@ register char *__stack_pointer __asm__ ("r1");
 
 #define HAS_COMPARE_AND_SWAP
 #define HAS_COMPARE_AND_SWAP_WITH_RELEASE_SEMANTICS
-#define IMPLEMENT_TAS_WITH_CAS
+#define MEMORY_BARRIER() __asm__ __volatile__("": : :"memory")
 
 /* Atomically:  If *PTR == OLD, set *PTR to NEW and return true,
    otherwise do nothing and return false.  */
 PT_EI int __compare_and_swap (long *ptr, long old, long new)
 {
-  unsigned long psw;
-
-  /* disable interrupts  */
-  /* This is ugly ugly ugly! */
-  __asm__ __volatile__ ("mfs	%0, rmsr;"
-			"andi	r3, %0, ~2;"
-			"mts	rmsr, r3;"
-			: "=&r" (psw)
-			:
-			: "r3");
+  long prev, cmp, retval;
+  __asm__ __volatile__ ("         addi    %2, r0, 0;"
+                        "1:       lwx     %0, %3, r0;"
+                        "         cmp     %1, %0, %4;"
+                        "         bnei    %1, 2f;"
+                        "         swx     %5, %3, r0;"
+                        "         addic   %1, r0, 0;"
+                        "         bnei    %1, 1b;"
+                        "         addi    %2, r0, 1;"
+                        "2:"
+                        : "=&r" (prev), "=&r" (cmp), "=&r" (retval)
+                        : "r" (ptr), "r" (old), "r" (new)
+                        : "cc", "memory");
 
-  if (likely (*ptr == old))
-    {
-      *ptr = new;
-      __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw)); /* re-enable */
-      return 1;
-    }
-  else
-    {
-      __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw)); /* re-enable */
-      return 0;
-    }
+  return retval;
 }
 
-/* like above's __compare_and_swap() but it first syncs the memory
-   (This is also the difference between both functions in e.g.
-    ../powerpc/pt-machine.h)
-   Doing this additional sync fixes a hang of __pthread_alt_unlock()
-   (Falk Brettschneider <fbrettschneider@baumeroptronic.de>) */
 PT_EI int
 __compare_and_swap_with_release_semantics (long *p,
 					   long oldval, long newval)
 {
-  __asm__ __volatile__ ("" : : : "memory"); /*MEMORY_BARRIER ();*/
+  MEMORY_BARRIER();
   return __compare_and_swap (p, oldval, newval);
 }
 
-
-#ifndef IMPLEMENT_TAS_WITH_CAS
-/* Spinlock implementation; required.  */
+/* Spinlock implementation; required.  */ 
 PT_EI long int testandset (int *spinlock)
 {
-	unsigned psw;
+  long int retval;
 
-	/* disable interrupts */
-	__asm__ __volatile__ ("mfs	%0, rmsr;"
-			      "andi	r3, %0, ~2;"
-			       "mts	rmsr, r3;"
-			: "=&r" (psw)
-			:
-			: "r3");
+  __asm__ __volatile__ ("1:       lwx     %0, %1, r0;"
+                        "         bnei    %0, 2f;"
+                        "         addik   %0, r0, 1;"
+                        "         swx     %0, %1, r0;"
+                        "         addic   %0, r0, 0;"
+                        "         bnei    %0, 1b;"
+                        "2:"
+                        : "=&r" (retval)
+                        : "r" (spinlock)
+                        : "cc", "memory");
 
-	if (*spinlock)
-	{
-		/* Enable ints */
-		__asm__ __volatile__ ("mts	rmsr, %0;" :: "r" (psw));
-		return 1;
-	} else {
-		*spinlock=1;
-		/* Enable ints */
-		__asm__ __volatile__ ("mts	rmsr, %0;" :: "r" (psw));
-		return 0;
-	}
+  return retval;
 }
 
-#endif
 #endif /* pt-machine.h */