usermode/library/atomic_ops/sparc.h

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.                                                 */

Generated on Sat Apr 23 11:43:34 2011 for Mnemosyne by  doxygen 1.4.7