00001 /* 00002 * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. 00003 * Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved. 00004 * Copyright (c) 1999-2003 by Hewlett-Packard Company. All rights reserved. 00005 * 00006 * 00007 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 00008 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 00009 * 00010 * Permission is hereby granted to use or copy this program 00011 * for any purpose, provided the above notices are retained on all copies. 00012 * Permission to modify the code and to distribute modified code is granted, 00013 * provided the above notices are retained, and a notice that the code was 00014 * modified is included with the above copyright notice. 00015 * 00016 */ 00017 00018 /* FIXME. Very incomplete. No support for sparc64. */ 00019 /* Non-ancient SPARCs provide compare-and-swap (casa). */ 00020 /* We should make that available. */ 00021 00022 #include "./aligned_atomic_load_store.h" 00023 00024 /* Real SPARC code uses TSO: */ 00025 #include "./ordered_except_wr.h" 00026 00027 /* Test_and_set location is just a byte. */ 00028 #include "./test_and_set_t_is_char.h" 00029 00030 AO_INLINE AO_TS_VAL_t 00031 AO_test_and_set_full(volatile AO_TS_t *addr) { 00032 AO_TS_VAL_t oldval; 00033 00034 __asm__ __volatile__("ldstub %1,%0" 00035 : "=r"(oldval), "=m"(*addr) 00036 : "m"(*addr) : "memory"); 00037 return oldval; 00038 } 00039 00040 #define AO_HAVE_test_and_set_full 00041 00042 #ifndef AO_NO_SPARC_V9 00043 /* Returns nonzero if the comparison succeeded. */ 00044 AO_INLINE int 00045 AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) { 00046 char ret; 00047 __asm__ __volatile__ ("membar #StoreLoad | #LoadLoad\n\t" 00048 # if defined(__arch64__) 00049 "casx [%2],%0,%1\n\t" 00050 # else 00051 "cas [%2],%0,%1\n\t" /* 32-bit version */ 00052 # endif 00053 "membar #StoreLoad | #StoreStore\n\t" 00054 "cmp %0,%1\n\t" 00055 "be,a 0f\n\t" 00056 "mov 1,%0\n\t"/* one insn after branch always executed */ 00057 "clr %0\n\t" 00058 "0:\n\t" 00059 : "=r" (ret), "+r" (new_val) 00060 : "r" (addr), "0" (old) 00061 : "memory", "cc"); 00062 return (int)ret; 00063 } 00064 00065 #define AO_HAVE_compare_and_swap_full 00066 #endif /* AO_NO_SPARC_V9 */ 00067 00068 /* FIXME: This needs to be extended for SPARC v8 and v9. */ 00069 /* SPARC V8 also has swap. V9 has CAS. */ 00070 /* There are barriers like membar #LoadStore. */ 00071 /* CASA (32-bit) and CASXA(64-bit) instructions were */ 00072 /* added in V9. */
1.4.7