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