boehm-gc: revert all CACAO-specific modifications; this is now an exact copy of the...
[cacao.git] / src / mm / boehm-gc / libatomic_ops-1.2 / src / atomic_ops / sysdeps / gcc / mips.h
1 /* \r
2  * Copyright (c) 2005,2007  Thiemo Seufer <ths@networkno.de>\r
3  *\r
4  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED\r
5  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.\r
6  *\r
7  * Permission is hereby granted to use or copy this program\r
8  * for any purpose,  provided the above notices are retained on all copies.\r
9  * Permission to modify the code and to distribute modified code is granted,\r
10  * provided the above notices are retained, and a notice that the code was\r
11  * modified is included with the above copyright notice.\r
12  */\r
13 \r
14 /*\r
15  * FIXME:  This should probably make finer distinctions.  SGI MIPS is\r
16  * much more strongly ordered, and in fact closer to sequentially\r
17  * consistent.  This is really aimed at modern embedded implementations.\r
18  * It looks to me like this assumes a 32-bit ABI.  -HB\r
19  */\r
20 \r
21 #include "../all_aligned_atomic_load_store.h"\r
22 #include "../acquire_release_volatile.h"\r
23 #include "../test_and_set_t_is_ao_t.h"\r
24 #include "../standard_ao_double_t.h"\r
25 \r
26 /* Data dependence does not imply read ordering.  */\r
27 #define AO_NO_DD_ORDERING\r
28 \r
29 AO_INLINE void\r
30 AO_nop_full(void)\r
31 {\r
32   __asm__ __volatile__(\r
33       "       .set push           \n"\r
34       "       .set mips2          \n"\r
35       "       .set noreorder      \n"\r
36       "       .set nomacro        \n"\r
37       "       sync                \n"\r
38       "       .set pop              "\r
39       : : : "memory");\r
40 }\r
41 \r
42 #define AO_HAVE_nop_full\r
43 \r
44 AO_INLINE int\r
45 AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val)\r
46 {\r
47   register int was_equal = 0;\r
48   register int temp;\r
49 \r
50   __asm__ __volatile__(\r
51       "       .set push           \n"\r
52       "       .set mips2          \n"\r
53       "       .set noreorder      \n"\r
54       "       .set nomacro        \n"\r
55       "1:     ll      %0, %1      \n"\r
56       "       bne     %0, %4, 2f  \n"\r
57       "        move   %0, %3      \n"\r
58       "       sc      %0, %1      \n"\r
59       "       .set pop            \n"\r
60       "       beqz    %0, 1b      \n"\r
61       "       li      %2, 1       \n"\r
62       "2:                           "\r
63       : "=&r" (temp), "+R" (*addr), "+r" (was_equal)\r
64       : "r" (new_val), "r" (old)\r
65       : "memory");\r
66   return was_equal;\r
67 }\r
68 \r
69 #define AO_HAVE_compare_and_swap\r
70 \r
71 /* FIXME: I think the implementations below should be automatically     */\r
72 /* generated if we omit them.  - HB                                     */\r
73 \r
74 AO_INLINE int\r
75 AO_compare_and_swap_acquire(volatile AO_t *addr, AO_t old, AO_t new_val) {\r
76   int result = AO_compare_and_swap(addr, old, new_val);\r
77   AO_nop_full();\r
78   return result;\r
79 }\r
80 \r
81 #define AO_HAVE_compare_and_swap_acquire\r
82 \r
83 AO_INLINE int\r
84 AO_compare_and_swap_release(volatile AO_t *addr, AO_t old, AO_t new_val) {\r
85   AO_nop_full();\r
86   return AO_compare_and_swap(addr, old, new_val);\r
87 }\r
88 \r
89 #define AO_HAVE_compare_and_swap_release\r
90 \r
91 AO_INLINE int\r
92 AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) {\r
93   AO_t result;\r
94   AO_nop_full();\r
95   result = AO_compare_and_swap(addr, old, new_val);\r
96   AO_nop_full();\r
97   return result;\r
98 }\r
99 \r
100 #define AO_HAVE_compare_and_swap_full\r
101 \r
102 /*\r
103  * FIXME: We should also implement fetch_and_add and or primitives\r
104  * directly.\r
105  */\r
106 \r
107 #include "../ao_t_is_int.h"\r