1 /*
2 * Copyright (C) 2006-2008 by Marc Boris Duerner
3 * Copyright (C) 2006 by Aloysius Indrayanto
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * As a special exception, you may use this file as part of a free
11 * software library without restriction. Specifically, if other files
12 * instantiate templates or use macros or inline functions from this
13 * file, or you compile this file and link it with other files to
14 * produce an executable, this file does not by itself cause the
15 * resulting executable to be covered by the GNU General Public
16 * License. This exception does not however invalidate any other
17 * reasons why the executable file might be covered by the GNU Library
18 * General Public License.
19 *
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30 #include <cxxtools/atomicity.gcc.mips.h>
31 #include <csignal>
32
33 namespace cxxtools {
34
atomicGet(volatile atomic_t & val)35 atomic_t atomicGet(volatile atomic_t& val)
36 {
37 asm volatile ("" : : : "memory");
38 return val;
39 }
40
41
atomicSet(volatile atomic_t & val,atomic_t n)42 void atomicSet(volatile atomic_t& val, atomic_t n)
43 {
44 val = n;
45 asm volatile ("" : : : "memory");
46 }
47
48
atomicIncrement(volatile atomic_t & val)49 atomic_t atomicIncrement(volatile atomic_t& val)
50 {
51 atomic_t tmp, result = 0;
52
53 asm volatile (" .set mips32\n"
54 "1: ll %0, %2\n"
55 " addu %1, %0, 1\n"
56 " sc %1, %2\n"
57 " beqz %1, 1b\n"
58 " .set mips0\n"
59 : "=&r" (result), "=&r" (tmp), "=m" (val)
60 : "m" (val));
61 return result + 1;
62 }
63
64
atomicDecrement(volatile atomic_t & val)65 atomic_t atomicDecrement(volatile atomic_t& val)
66 {
67 atomic_t tmp, result = 0;
68
69 asm volatile (" .set mips32\n"
70 "1: ll %0, %2\n"
71 " subu %1, %0, 1\n"
72 " sc %1, %2\n"
73 " beqz %1, 1b\n"
74 " .set mips0\n"
75 : "=&r" (result), "=&r" (tmp), "=m" (val)
76 : "m" (val));
77 return result - 1;
78 }
79
80
atomicCompareExchange(volatile atomic_t & dest,atomic_t exch,atomic_t comp)81 atomic_t atomicCompareExchange(volatile atomic_t& dest, atomic_t exch, atomic_t comp)
82 {
83 atomic_t old, tmp;
84
85 asm volatile (" .set mips32\n"
86 "1: ll %0, %2\n"
87 " bne %0, %5, 2f\n"
88 " move %1, %4\n"
89 " sc %1, %2\n"
90 " beqz %1, 1b\n"
91 "2: .set mips0\n"
92 : "=&r" (old), "=&r" (tmp), "=m" (dest)
93 : "m" (dest), "r" (exch), "r" (comp));
94 return(old);
95 }
96
97
atomicCompareExchange(void * volatile & dest,void * exch,void * comp)98 void* atomicCompareExchange(void* volatile& dest, void* exch, void* comp)
99 {
100 atomic_t* old;
101 atomic_t* tmp;
102
103 asm volatile (" .set mips32\n"
104 "1: ll %0, %2\n"
105 " bne %0, %5, 2f\n"
106 " move %1, %4\n"
107 " sc %1, %2\n"
108 " beqz %1, 1b\n"
109 "2: .set mips0\n"
110 : "=&r" (old), "=&r" (tmp), "=m" (dest)
111 : "m" (dest), "r" (exch), "r" (comp));
112 return(old);
113 }
114
115
atomicExchange(volatile atomic_t & dest,atomic_t exch)116 atomic_t atomicExchange(volatile atomic_t& dest, atomic_t exch)
117 {
118 atomic_t result, tmp;
119
120 asm volatile (" .set mips32\n"
121 "1: ll %0, %2\n"
122 " move %1, %4\n"
123 " sc %1, %2\n"
124 " beqz %1, 1b\n"
125 " .set mips0\n"
126 : "=&r" (result), "=&r" (tmp), "=m" (dest)
127 : "m" (dest), "r" (exch));
128 return(result);
129 }
130
131
atomicExchange(void * volatile & val,void * exch)132 void* atomicExchange(void* volatile& val, void* exch)
133 {
134 atomic_t* result, tmp;
135
136 asm volatile (" .set mips32\n"
137 "1: ll %0, %2\n"
138 " move %1, %4\n"
139 " sc %1, %2\n"
140 " beqz %1, 1b\n"
141 " .set mips0\n"
142 : "=&r" (result), "=&r" (tmp), "=m" (val)
143 : "m" (val), "r" (exch));
144 return(result);
145 }
146
147
atomicExchangeAdd(volatile atomic_t & dest,atomic_t add)148 atomic_t atomicExchangeAdd(volatile atomic_t& dest, atomic_t add)
149 {
150 atomic_t result, tmp;
151
152 asm volatile (" .set mips32\n"
153 "1: ll %0, %2\n"
154 " addu %1, %0, %4\n"
155 " sc %1, %2\n"
156 " beqz %1, 1b\n"
157 " .set mips0\n"
158 : "=&r" (result), "=&r" (tmp), "=m" (dest)
159 : "m" (dest), "r" (add));
160 return result;
161 }
162
163 } // namespace cxxtools
164