-/*
- * Copyright (c) 2008 Hewlett-Packard Development Company, L.P.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- */
-???? needs work
-
-#include "../all_atomic_load_store.h"
-
-??? What is mips memory ordering anyway???
-
-#define AO_TS_t int
-
-# ifdef LINUX
-# include <sys/tas.h>
-# define GC_test_and_set(addr) _test_and_set((int *) addr,1)
-# define GC_TEST_AND_SET_DEFINED
-# elif __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) \
- || !defined(_COMPILER_VERSION) || _COMPILER_VERSION < 700
-# ifdef __GNUC__
-# define GC_test_and_set(addr) _test_and_set((void *)addr,1)
-# else
-# define GC_test_and_set(addr) test_and_set((void *)addr,1)
-# endif
-# else
-# include <sgidefs.h>
-# include <mutex.h>
-# define GC_test_and_set(addr) __test_and_set32((void *)addr,1)
-# define GC_clear(addr) __lock_release(addr);
-# define GC_CLEAR_DEFINED
-# endif
-
-
-#define AO_HAVE_test_and_set_full
-
+/* \r
+ * Copyright (c) 2005,2007 Thiemo Seufer <ths@networkno.de>\r
+ *\r
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED\r
+ * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.\r
+ *\r
+ * Permission is hereby granted to use or copy this program\r
+ * for any purpose, provided the above notices are retained on all copies.\r
+ * Permission to modify the code and to distribute modified code is granted,\r
+ * provided the above notices are retained, and a notice that the code was\r
+ * modified is included with the above copyright notice.\r
+ */\r
+\r
+/*\r
+ * FIXME: This should probably make finer distinctions. SGI MIPS is\r
+ * much more strongly ordered, and in fact closer to sequentially\r
+ * consistent. This is really aimed at modern embedded implementations.\r
+ * It looks to me like this assumes a 32-bit ABI. -HB\r
+ */\r
+\r
+#include "../all_aligned_atomic_load_store.h"\r
+#include "../acquire_release_volatile.h"\r
+#include "../test_and_set_t_is_ao_t.h"\r
+#include "../standard_ao_double_t.h"\r
+\r
+/* Data dependence does not imply read ordering. */\r
+#define AO_NO_DD_ORDERING\r
+\r
+AO_INLINE void\r
+AO_nop_full()\r
+{\r
+ __asm__ __volatile__(\r
+ " .set push \n"\r
+ " .set mips2 \n"\r
+ " .set noreorder \n"\r
+ " .set nomacro \n"\r
+ " sync \n"\r
+ " .set pop "\r
+ : : : "memory");\r
+}\r
+\r
+#define AO_HAVE_nop_full\r
+\r
+AO_INLINE int\r
+AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val)\r
+{\r
+ register int was_equal = 0;\r
+ register int temp;\r
+\r
+ __asm__ __volatile__(\r
+ " .set push \n"\r
+ " .set mips2 \n"\r
+ " .set noreorder \n"\r
+ " .set nomacro \n"\r
+ "1: ll %0, %1 \n"\r
+ " bne %0, %4, 2f \n"\r
+ " move %0, %3 \n"\r
+ " sc %0, %1 \n"\r
+ " .set pop \n"\r
+ " beqz %0, 1b \n"\r
+ " li %2, 1 \n"\r
+ "2: "\r
+ : "=&r" (temp), "+R" (*addr), "+r" (was_equal)\r
+ : "r" (new_val), "r" (old)\r
+ : "memory");\r
+ return was_equal;\r
+}\r
+\r
+#define AO_HAVE_compare_and_swap\r
+\r
+/* FIXME: I think the implementations below should be automatically */\r
+/* generated if we omit them. - HB */\r
+\r
+AO_INLINE int\r
+AO_compare_and_swap_acquire(volatile AO_t *addr, AO_t old, AO_t new_val) {\r
+ int result = AO_compare_and_swap(addr, old, new_val);\r
+ AO_nop_full();\r
+ return result;\r
+}\r
+\r
+#define AO_HAVE_compare_and_swap_acquire\r
+\r
+AO_INLINE int\r
+AO_compare_and_swap_release(volatile AO_t *addr, AO_t old, AO_t new_val) {\r
+ AO_nop_full();\r
+ return AO_compare_and_swap(addr, old, new_val);\r
+}\r
+\r
+#define AO_HAVE_compare_and_swap_release\r
+\r
+AO_INLINE int\r
+AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) {\r
+ AO_t result;\r
+ AO_nop_full();\r
+ result = AO_compare_and_swap(addr, old, new_val);\r
+ AO_nop_full();\r
+ return result;\r
+}\r
+\r
+#define AO_HAVE_compare_and_swap_full\r
+\r
+/*\r
+ * FIXME: We should also implement fetch_and_add and or primitives\r
+ * directly.\r
+ */\r
+\r
+#include "../ao_t_is_int.h"\r