1// Low-level functions for atomic operations: Sparc version -*- C++ -*- 2 3// Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2009 4// Free Software Foundation, Inc. 5// 6// This file is part of the GNU ISO C++ Library. This library is free 7// software; you can redistribute it and/or modify it under the 8// terms of the GNU General Public License as published by the 9// Free Software Foundation; either version 3, or (at your option) 10// any later version. 11 12// This library is distributed in the hope that it will be useful, 13// but WITHOUT ANY WARRANTY; without even the implied warranty of 14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15// GNU General Public License for more details. 16 17// Under Section 7 of GPL version 3, you are granted additional 18// permissions described in the GCC Runtime Library Exception, version 19// 3.1, as published by the Free Software Foundation. 20 21// You should have received a copy of the GNU General Public License and 22// a copy of the GCC Runtime Library Exception along with this program; 23// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24// <http://www.gnu.org/licenses/>. 25 26#include <ext/atomicity.h> 27 28_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 29 30#ifdef __arch64__ 31 _Atomic_word 32 __attribute__ ((__unused__)) 33 __exchange_and_add(volatile _Atomic_word* __mem, int __val) throw () 34 { 35 _Atomic_word __tmp1, __tmp2; 36 _Atomic_word __val_extended = __val; 37 38 __asm__ __volatile__("1: ldx [%3], %0\n\t" 39 " add %0, %4, %1\n\t" 40 " casx [%3], %0, %1\n\t" 41 " sub %0, %1, %0\n\t" 42 " brnz,pn %0, 1b\n\t" 43 " nop" 44 : "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__mem) 45 : "r" (__mem), "r" (__val_extended), "m" (*__mem)); 46 return __tmp2; 47 } 48 49 void 50 __attribute__ ((__unused__)) 51 __atomic_add(volatile _Atomic_word* __mem, int __val) throw () 52 { 53 _Atomic_word __tmp1, __tmp2; 54 _Atomic_word __val_extended = __val; 55 56 __asm__ __volatile__("1: ldx [%3], %0\n\t" 57 " add %0, %4, %1\n\t" 58 " casx [%3], %0, %1\n\t" 59 " sub %0, %1, %0\n\t" 60 " brnz,pn %0, 1b\n\t" 61 " nop" 62 : "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__mem) 63 : "r" (__mem), "r" (__val_extended), "m" (*__mem)); 64 } 65 66#else /* __arch32__ */ 67 68 template<int __inst> 69 struct _Atomicity_lock 70 { 71 static unsigned char _S_atomicity_lock; 72 }; 73 74 template<int __inst> 75 unsigned char _Atomicity_lock<__inst>::_S_atomicity_lock = 0; 76 77 template unsigned char _Atomicity_lock<0>::_S_atomicity_lock; 78 79 _Atomic_word 80 __attribute__ ((__unused__)) 81 __exchange_and_add(volatile _Atomic_word* __mem, int __val) throw () 82 { 83 _Atomic_word __result, __tmp; 84 85 __asm__ __volatile__("1: ldstub [%1], %0\n\t" 86 " cmp %0, 0\n\t" 87 " bne 1b\n\t" 88 " nop" 89 : "=&r" (__tmp) 90 : "r" (&_Atomicity_lock<0>::_S_atomicity_lock) 91 : "memory"); 92 __result = *__mem; 93 *__mem += __val; 94 __asm__ __volatile__("stb %%g0, [%0]" 95 : /* no outputs */ 96 : "r" (&_Atomicity_lock<0>::_S_atomicity_lock) 97 : "memory"); 98 return __result; 99 } 100 101 void 102 __attribute__ ((__unused__)) 103 __atomic_add(volatile _Atomic_word* __mem, int __val) throw () 104 { 105 _Atomic_word __tmp; 106 107 __asm__ __volatile__("1: ldstub [%1], %0\n\t" 108 " cmp %0, 0\n\t" 109 " bne 1b\n\t" 110 " nop" 111 : "=&r" (__tmp) 112 : "r" (&_Atomicity_lock<0>::_S_atomicity_lock) 113 : "memory"); 114 *__mem += __val; 115 __asm__ __volatile__("stb %%g0, [%0]" 116 : /* no outputs */ 117 : "r" (&_Atomicity_lock<0>::_S_atomicity_lock) 118 : "memory"); 119 } 120#endif /* __arch32__ */ 121 122_GLIBCXX_END_NAMESPACE 123