about summary refs log tree commit diff
path: root/linuxthreads/sysdeps/mips/pt-machine.h
diff options
context:
space:
mode:
Diffstat (limited to 'linuxthreads/sysdeps/mips/pt-machine.h')
-rw-r--r--linuxthreads/sysdeps/mips/pt-machine.h91
1 files changed, 53 insertions, 38 deletions
diff --git a/linuxthreads/sysdeps/mips/pt-machine.h b/linuxthreads/sysdeps/mips/pt-machine.h
index 50765b183c..16e264017d 100644
--- a/linuxthreads/sysdeps/mips/pt-machine.h
+++ b/linuxthreads/sysdeps/mips/pt-machine.h
@@ -18,13 +18,10 @@
    You should have received a copy of the GNU Library General Public
    License along with the GNU C Library; see the file COPYING.LIB.  If
    not, write to the Free Software Foundation, Inc.,
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-   TODO: This version makes use of MIPS ISA 2 features.  It won't
-   work on ISA 1.  These machines will have to take the overhead of
-   a sysmips(MIPS_ATOMIC_SET, ...) syscall which isn't implemented
-   yet correctly.  There is however a better solution for R3000
-   uniprocessor machines possible.  */
+#include <sgidefs.h>
+#include <sys/tas.h>
 
 #ifndef PT_EI
 # define PT_EI extern inline
@@ -35,30 +32,43 @@
 
 
 /* Spinlock implementation; required.  */
+
+#if (_MIPS_ISA >= _MIPS_ISA_MIPS2)
+
 PT_EI long int
 testandset (int *spinlock)
 {
   long int ret, temp;
 
-  __asm__ __volatile__(
-	"# Inline spinlock test & set\n\t"
-	".set\tmips2\n"
-	"1:\tll\t%0,%3\n\t"
-	"bnez\t%0,2f\n\t"
-	".set\tnoreorder\n\t"
-	"li\t%1,1\n\t"
-	".set\treorder\n\t"
-	"sc\t%1,%2\n\t"
-	"beqz\t%1,1b\n"
-	"2:\t.set\tmips0\n\t"
-	"/* End spinlock test & set */"
-	: "=&r"(ret), "=&r" (temp), "=m"(*spinlock)
-	: "m"(*spinlock)
-	: "memory");
+  __asm__ __volatile__
+    ("/* Inline spinlock test & set */\n\t"
+     "1:\n\t"
+     "ll	%0,%3\n\t"
+     ".set	push\n\t"
+     ".set	noreorder\n\t"
+     "bnez	%0,2f\n\t"
+     " li	%1,1\n\t"
+     ".set	pop\n\t"
+     "sc	%1,%2\n\t"
+     "beqz	%1,1b\n"
+     "2:\n\t"
+     "/* End spinlock test & set */"
+     : "=&r" (ret), "=&r" (temp), "=m" (*spinlock)
+     : "m" (*spinlock)
+     : "memory");
 
   return ret;
 }
 
+#else /* !(_MIPS_ISA >= _MIPS_ISA_MIPS2) */
+
+PT_EI long int
+testandset (int *spinlock)
+{
+  return _test_and_set (spinlock, 1);
+}
+#endif /* !(_MIPS_ISA >= _MIPS_ISA_MIPS2) */
+
 
 /* Get some notion of the current stack.  Need not be exactly the top
    of the stack, just something somewhere in the current frame.  */
@@ -68,27 +78,32 @@ register char * stack_pointer __asm__ ("$29");
 
 /* Compare-and-swap for semaphores. */
 
+#if (_MIPS_ISA >= _MIPS_ISA_MIPS2)
+
 #define HAS_COMPARE_AND_SWAP
 PT_EI int
 __compare_and_swap (long int *p, long int oldval, long int newval)
 {
-  long ret;
-
-  __asm__ __volatile__ (
-	"/* Inline compare & swap */\n\t"
-	".set\tmips2\n"
-	"1:\tll\t%0,%4\n\t"
-	".set\tnoreorder\n\t"
-	"bne\t%0,%2,2f\n\t"
-	"move\t%0,%3\n\t"
-	".set\treorder\n\t"
-	"sc\t%0,%1\n\t"
-	"beqz\t%0,1b\n"
-	"2:\t.set\tmips0\n\t"
-	"/* End compare & swap */"
-	: "=&r"(ret), "=m"(*p)
-	: "r"(oldval), "r"(newval), "m"(*p)
-	: "memory");
+  long int ret;
+
+  __asm__ __volatile__
+    ("/* Inline compare & swap */\n\t"
+     "1:\n\t"
+     "ll	%0,%4\n\t"
+     ".set	push\n"
+     ".set	noreorder\n\t"
+     "bne	%0,%2,2f\n\t"
+     " move	%0,%3\n\t"
+     ".set	pop\n\t"
+     "sc	%0,%1\n\t"
+     "beqz	%0,1b\n"
+     "2:\n\t"
+     "/* End compare & swap */"
+     : "=&r" (ret), "=m" (*p)
+     : "r" (oldval), "r" (newval), "m" (*p)
+     : "memory");
 
   return ret;
 }
+
+#endif /* (_MIPS_ISA >= _MIPS_ISA_MIPS2) */