root/opal/include/opal/sys/sparcv9/atomic.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. opal_atomic_mb
  2. opal_atomic_rmb
  3. opal_atomic_wmb
  4. opal_atomic_isync
  5. opal_atomic_compare_exchange_strong_32
  6. opal_atomic_compare_exchange_strong_acq_32
  7. opal_atomic_compare_exchange_strong_rel_32
  8. opal_atomic_compare_exchange_strong_64
  9. opal_atomic_compare_exchange_strong_64
  10. opal_atomic_compare_exchange_strong_acq_64
  11. opal_atomic_compare_exchange_strong_rel_64

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2005 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2007      Sun Microsystems, Inc.  All rights reserverd.
  14  * Copyright (c) 2016      Research Organization for Information Science
  15  *                         and Technology (RIST). All rights reserved.
  16  * Copyright (c) 2017-2018 Los Alamos National Security, LLC. All rights
  17  *                         reserved.
  18  * $COPYRIGHT$
  19  *
  20  * Additional copyrights may follow
  21  *
  22  * $HEADER$
  23  */
  24 
  25 #ifndef OPAL_SYS_ARCH_ATOMIC_H
  26 #define OPAL_SYS_ARCH_ATOMIC_H 1
  27 
  28 /*
  29  * On sparc v9, use casa and casxa (compare and swap) instructions.
  30  */
  31 
  32 #define ASI_P "0x80"
  33 
  34 #define MEMBAR(type) __asm__  __volatile__ ("membar " type : : : "memory")
  35 
  36 
  37 /**********************************************************************
  38  *
  39  * Define constants for Sparc v9 (Ultra Sparc)
  40  *
  41  *********************************************************************/
  42 #define OPAL_HAVE_ATOMIC_MEM_BARRIER 1
  43 
  44 #define OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_32 1
  45 
  46 #define OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_64 1
  47 
  48 
  49 /**********************************************************************
  50  *
  51  * Memory Barriers
  52  *
  53  *********************************************************************/
  54 #if OPAL_GCC_INLINE_ASSEMBLY
  55 
  56 static inline void opal_atomic_mb(void)
  57 {
  58     MEMBAR("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad");
  59 }
  60 
  61 
  62 static inline void opal_atomic_rmb(void)
  63 {
  64     MEMBAR("#LoadLoad");
  65 }
  66 
  67 
  68 static inline void opal_atomic_wmb(void)
  69 {
  70     MEMBAR("#StoreStore");
  71 }
  72 
  73 static inline void opal_atomic_isync(void)
  74 {
  75 }
  76 
  77 
  78 #endif /* OPAL_GCC_INLINE_ASSEMBLY */
  79 
  80 
  81 /**********************************************************************
  82  *
  83  * Atomic math operations
  84  *
  85  *********************************************************************/
  86 #if OPAL_GCC_INLINE_ASSEMBLY
  87 
  88 static inline bool opal_atomic_compare_exchange_strong_32 (opal_atomic_int32_t *addr, int32_t *oldval, int32_t newval)
  89 {
  90     /* casa [reg(rs1)] %asi, reg(rs2), reg(rd)
  91      *
  92      * if (*(reg(rs1)) == reg(rs2) )
  93      *    swap reg(rd), *(reg(rs1))
  94      * else
  95      *    reg(rd) = *(reg(rs1))
  96      */
  97 
  98     int32_t prev = newval;
  99     bool ret;
 100 
 101     __asm__ __volatile__("casa [%1] " ASI_P ", %2, %0"
 102                          : "+r" (prev)
 103                          : "r" (addr), "r" (*oldval));
 104     ret = (prev == *oldval);
 105     *oldval = prev;
 106     return ret;
 107 }
 108 
 109 
 110 static inline bool opal_atomic_compare_exchange_strong_acq_32 (opal_atomic_int32_t *addr, int32_t *oldval, int32_t newval)
 111 {
 112     bool rc;
 113 
 114     rc = opal_atomic_compare_exchange_strong_32 (addr, oldval, newval);
 115     opal_atomic_rmb();
 116 
 117     return rc;
 118 }
 119 
 120 
 121 static inline bool opal_atomic_compare_exchange_strong_rel_32 (opal_atomic_int32_t *addr, int32_t *oldval, int32_t newval)
 122 {
 123     opal_atomic_wmb();
 124     return opal_atomic_compare_exchange_strong_32 (addr, oldval, newval);
 125 }
 126 
 127 
 128 #if OPAL_ASSEMBLY_ARCH == OPAL_SPARCV9_64
 129 
 130 static inline bool opal_atomic_compare_exchange_strong_64 (opal_atomic_int64_t *addr, int64_t *oldval, int64_t newval)
 131 {
 132     /* casa [reg(rs1)] %asi, reg(rs2), reg(rd)
 133      *
 134      * if (*(reg(rs1)) == reg(rs1) )
 135      *    swap reg(rd), *(reg(rs1))
 136      * else
 137      *    reg(rd) = *(reg(rs1))
 138      */
 139     int64_t prev = newval;
 140     bool ret;
 141 
 142     __asm__ __volatile__("casxa [%1] " ASI_P ", %2, %0"
 143                          : "+r" (prev)
 144                          : "r" (addr), "r" (*oldval));
 145     ret = (prev == *oldval);
 146     *oldval = prev;
 147     return ret;
 148 }
 149 
 150 #else /* OPAL_ASSEMBLY_ARCH == OPAL_SPARCV9_64 */
 151 
 152 static inline bool opal_atomic_compare_exchange_strong_64 (opal_atomic_int64_t *addr, int64_t *oldval, int64_t newval)
 153 {
 154     /* casa [reg(rs1)] %asi, reg(rs2), reg(rd)
 155      *
 156      * if (*(reg(rs1)) == reg(rs1) )
 157      *    swap reg(rd), *(reg(rs1))
 158      * else
 159      *    reg(rd) = *(reg(rs1))
 160      *
 161      */
 162     int64_t prev = newval;
 163     bool ret;
 164 
 165     __asm__ __volatile__(
 166                        "ldx %0, %%g1               \n\t" /* g1 = ret */
 167                        "ldx %2, %%g2               \n\t" /* g2 = oldval */
 168                        "casxa [%1] " ASI_P ", %%g2, %%g1 \n\t"
 169                        "stx %%g1, %0               \n"
 170                        : "+m"(prev)
 171                        : "r"(addr), "m"(*oldval)
 172                        : "%g1", "%g2"
 173                        );
 174 
 175    ret = (prev == *oldval);
 176    *oldval = prev;
 177    return ret;
 178 }
 179 
 180 #endif /* OPAL_ASSEMBLY_ARCH == OPAL_SPARCV9_64 */
 181 
 182 static inline bool opal_atomic_compare_exchange_strong_acq_64 (opal_atomic_int64_t *addr, int64_t *oldval, int64_t newval)
 183 {
 184     bool rc;
 185 
 186     rc = opal_atomic_compare_exchange_strong_64 (addr, oldval, newval);
 187     opal_atomic_rmb();
 188 
 189     return rc;
 190 }
 191 
 192 
 193 static inline bool opal_atomic_compare_exchange_strong_rel_64 (opal_atomic_int64_t *addr, int64_t *oldval, int64_t newval)
 194 {
 195     opal_atomic_wmb();
 196     return opal_atomic_compare_exchange_strong_64 (addr, oldval, newval);
 197 }
 198 
 199 #endif /* OPAL_GCC_INLINE_ASSEMBLY */
 200 
 201 
 202 #endif /* ! OPAL_SYS_ARCH_ATOMIC_H */

/* [<][>][^][v][top][bottom][index][help] */