atomicity.h revision 132720
1// Low-level functions for atomic operations: Sparc version  -*- C++ -*-
2
3// Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 2, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License along
17// with this library; see the file COPYING.  If not, write to the Free
18// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19// USA.
20
21// As a special exception, you may use this file as part of a free software
22// library without restriction.  Specifically, if other files instantiate
23// templates or use macros or inline functions from this file, or you compile
24// this file and link it with other files to produce an executable, this
25// file does not by itself cause the resulting executable to be covered by
26// the GNU General Public License.  This exception does not however
27// invalidate any other reasons why the executable file might be covered by
28// the GNU General Public License.
29
30#include <bits/atomicity.h>
31
32namespace __gnu_cxx
33{
34#ifdef __arch64__
35  _Atomic_word
36  __attribute__ ((__unused__))
37  __exchange_and_add(volatile _Atomic_word* __mem, int __val)
38  {
39    _Atomic_word __tmp1, __tmp2;
40    _Atomic_word __val_extended = __val;
41
42    __asm__ __volatile__("1:	ldx	[%3], %0\n\t"
43			 "	add	%0, %4, %1\n\t"
44			 "	casx	[%3], %0, %1\n\t"
45			 "	sub	%0, %1, %0\n\t"
46			 "	brnz,pn	%0, 1b\n\t"
47			 "	 nop"
48			 : "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__mem)
49			 : "r" (__mem), "r" (__val_extended), "m" (*__mem));
50    return __tmp2;
51  }
52
53  void
54  __attribute__ ((__unused__))
55  __atomic_add(volatile _Atomic_word* __mem, int __val)
56  {
57    _Atomic_word __tmp1, __tmp2;
58    _Atomic_word __val_extended = __val;
59
60    __asm__ __volatile__("1:	ldx	[%3], %0\n\t"
61			 "	add	%0, %4, %1\n\t"
62			 "	casx	[%3], %0, %1\n\t"
63			 "	sub	%0, %1, %0\n\t"
64			 "	brnz,pn	%0, 1b\n\t"
65			 "	 nop"
66			 : "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__mem)
67			 : "r" (__mem), "r" (__val_extended), "m" (*__mem));
68  }
69
70#else /* __arch32__ */
71
72  template<int __inst>
73    struct _Atomicity_lock
74    {
75      static unsigned char _S_atomicity_lock;
76    };
77
78  template<int __inst>
79  unsigned char _Atomicity_lock<__inst>::_S_atomicity_lock = 0;
80
81  template unsigned char _Atomicity_lock<0>::_S_atomicity_lock;
82
83  _Atomic_word
84  __attribute__ ((__unused__))
85  __exchange_and_add(volatile _Atomic_word* __mem, int __val)
86  {
87    _Atomic_word __result, __tmp;
88
89    __asm__ __volatile__("1:	ldstub	[%1], %0\n\t"
90			 "	cmp	%0, 0\n\t"
91			 "	bne	1b\n\t"
92			 "	 nop"
93			 : "=&r" (__tmp)
94			 : "r" (&_Atomicity_lock<0>::_S_atomicity_lock)
95			 : "memory");
96    __result = *__mem;
97    *__mem += __val;
98    __asm__ __volatile__("stb	%%g0, [%0]"
99			 : /* no outputs */
100			 : "r" (&_Atomicity_lock<0>::_S_atomicity_lock)
101			 : "memory");
102    return __result;
103  }
104
105  void
106  __attribute__ ((__unused__))
107  __atomic_add(volatile _Atomic_word* __mem, int __val)
108  {
109    _Atomic_word __tmp;
110
111    __asm__ __volatile__("1:	ldstub	[%1], %0\n\t"
112			 "	cmp	%0, 0\n\t"
113			 "	bne	1b\n\t"
114			 "	 nop"
115			 : "=&r" (__tmp)
116			 : "r" (&_Atomicity_lock<0>::_S_atomicity_lock)
117			 : "memory");
118    *__mem += __val;
119    __asm__ __volatile__("stb	%%g0, [%0]"
120			 : /* no outputs */
121			 : "r" (&_Atomicity_lock<0>::_S_atomicity_lock)
122			 : "memory");
123  }
124#endif /* __arch32__ */
125} // namespace __gnu_cxx
126