Home | History | Annotate | Line # | Download | only in sparc
      1 // Low-level functions for atomic operations: Sparc version  -*- C++ -*-
      2 
      3 // Copyright (C) 1999-2024 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 3, 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 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 #include <ext/atomicity.h>
     26 
     27 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
     28 {
     29 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     30 
     31 #ifdef __arch64__
     32   _Atomic_word
     33   __attribute__ ((__unused__))
     34   __exchange_and_add(volatile _Atomic_word* __mem, int __val) throw ()
     35   {
     36     _Atomic_word __tmp1, __tmp2;
     37     _Atomic_word __val_extended = __val;
     38 
     39     __asm__ __volatile__("1:	ldx	[%3], %0\n\t"
     40 			 "	add	%0, %4, %1\n\t"
     41 			 "	casx	[%3], %0, %1\n\t"
     42 			 "	sub	%0, %1, %0\n\t"
     43 			 "	brnz,pn	%0, 1b\n\t"
     44 			 "	 nop"
     45 			 : "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__mem)
     46 			 : "r" (__mem), "r" (__val_extended), "m" (*__mem));
     47     return __tmp2;
     48   }
     49 
     50   void
     51   __attribute__ ((__unused__))
     52   __atomic_add(volatile _Atomic_word* __mem, int __val) throw ()
     53   {
     54     _Atomic_word __tmp1, __tmp2;
     55     _Atomic_word __val_extended = __val;
     56 
     57     __asm__ __volatile__("1:	ldx	[%3], %0\n\t"
     58 			 "	add	%0, %4, %1\n\t"
     59 			 "	casx	[%3], %0, %1\n\t"
     60 			 "	sub	%0, %1, %0\n\t"
     61 			 "	brnz,pn	%0, 1b\n\t"
     62 			 "	 nop"
     63 			 : "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__mem)
     64 			 : "r" (__mem), "r" (__val_extended), "m" (*__mem));
     65   }
     66 
     67 #else /* __arch32__ */
     68 
     69   template<int __inst>
     70     struct _Atomicity_lock
     71     {
     72       static unsigned char _S_atomicity_lock;
     73     };
     74 
     75   template<int __inst>
     76   unsigned char _Atomicity_lock<__inst>::_S_atomicity_lock = 0;
     77 
     78   template unsigned char _Atomicity_lock<0>::_S_atomicity_lock;
     79 
     80   _Atomic_word
     81   __attribute__ ((__unused__))
     82   __exchange_and_add(volatile _Atomic_word* __mem, int __val) throw ()
     83   {
     84     _Atomic_word __result, __tmp;
     85 
     86     __asm__ __volatile__("1:	ldstub	[%1], %0\n\t"
     87 			 "	cmp	%0, 0\n\t"
     88 			 "	bne	1b\n\t"
     89 			 "	 nop"
     90 			 : "=&r" (__tmp)
     91 			 : "r" (&_Atomicity_lock<0>::_S_atomicity_lock)
     92 			 : "memory");
     93     __result = *__mem;
     94     *__mem += __val;
     95     __asm__ __volatile__("stb	%%g0, [%0]"
     96 			 : /* no outputs */
     97 			 : "r" (&_Atomicity_lock<0>::_S_atomicity_lock)
     98 			 : "memory");
     99     return __result;
    100   }
    101 
    102   void
    103   __attribute__ ((__unused__))
    104   __atomic_add(volatile _Atomic_word* __mem, int __val) throw ()
    105   {
    106     _Atomic_word __tmp;
    107 
    108     __asm__ __volatile__("1:	ldstub	[%1], %0\n\t"
    109 			 "	cmp	%0, 0\n\t"
    110 			 "	bne	1b\n\t"
    111 			 "	 nop"
    112 			 : "=&r" (__tmp)
    113 			 : "r" (&_Atomicity_lock<0>::_S_atomicity_lock)
    114 			 : "memory");
    115     *__mem += __val;
    116     __asm__ __volatile__("stb	%%g0, [%0]"
    117 			 : /* no outputs */
    118 			 : "r" (&_Atomicity_lock<0>::_S_atomicity_lock)
    119 			 : "memory");
    120   }
    121 #endif /* __arch32__ */
    122 
    123 _GLIBCXX_END_NAMESPACE_VERSION
    124 } // namespace
    125