linux/arch/metag/include/asm/atomic_lnkget.h
<<
>>
Prefs
   1#ifndef __ASM_METAG_ATOMIC_LNKGET_H
   2#define __ASM_METAG_ATOMIC_LNKGET_H
   3
   4#define ATOMIC_INIT(i)  { (i) }
   5
   6#define atomic_set(v, i)                ((v)->counter = (i))
   7
   8#include <linux/compiler.h>
   9
  10#include <asm/barrier.h>
  11
  12/*
  13 * None of these asm statements clobber memory as LNKSET writes around
  14 * the cache so the memory it modifies cannot safely be read by any means
  15 * other than these accessors.
  16 */
  17
  18static inline int atomic_read(const atomic_t *v)
  19{
  20        int temp;
  21
  22        asm volatile (
  23                "LNKGETD %0, [%1]\n"
  24                : "=da" (temp)
  25                : "da" (&v->counter));
  26
  27        return temp;
  28}
  29
  30static inline void atomic_add(int i, atomic_t *v)
  31{
  32        int temp;
  33
  34        asm volatile (
  35                "1:     LNKGETD %0, [%1]\n"
  36                "       ADD     %0, %0, %2\n"
  37                "       LNKSETD [%1], %0\n"
  38                "       DEFR    %0, TXSTAT\n"
  39                "       ANDT    %0, %0, #HI(0x3f000000)\n"
  40                "       CMPT    %0, #HI(0x02000000)\n"
  41                "       BNZ     1b\n"
  42                : "=&d" (temp)
  43                : "da" (&v->counter), "bd" (i)
  44                : "cc");
  45}
  46
  47static inline void atomic_sub(int i, atomic_t *v)
  48{
  49        int temp;
  50
  51        asm volatile (
  52                "1:     LNKGETD %0, [%1]\n"
  53                "       SUB     %0, %0, %2\n"
  54                "       LNKSETD [%1], %0\n"
  55                "       DEFR    %0, TXSTAT\n"
  56                "       ANDT    %0, %0, #HI(0x3f000000)\n"
  57                "       CMPT    %0, #HI(0x02000000)\n"
  58                "       BNZ 1b\n"
  59                : "=&d" (temp)
  60                : "da" (&v->counter), "bd" (i)
  61                : "cc");
  62}
  63
  64static inline int atomic_add_return(int i, atomic_t *v)
  65{
  66        int result, temp;
  67
  68        smp_mb();
  69
  70        asm volatile (
  71                "1:     LNKGETD %1, [%2]\n"
  72                "       ADD     %1, %1, %3\n"
  73                "       LNKSETD [%2], %1\n"
  74                "       DEFR    %0, TXSTAT\n"
  75                "       ANDT    %0, %0, #HI(0x3f000000)\n"
  76                "       CMPT    %0, #HI(0x02000000)\n"
  77                "       BNZ 1b\n"
  78                : "=&d" (temp), "=&da" (result)
  79                : "da" (&v->counter), "bd" (i)
  80                : "cc");
  81
  82        smp_mb();
  83
  84        return result;
  85}
  86
  87static inline int atomic_sub_return(int i, atomic_t *v)
  88{
  89        int result, temp;
  90
  91        smp_mb();
  92
  93        asm volatile (
  94                "1:     LNKGETD %1, [%2]\n"
  95                "       SUB     %1, %1, %3\n"
  96                "       LNKSETD [%2], %1\n"
  97                "       DEFR    %0, TXSTAT\n"
  98                "       ANDT    %0, %0, #HI(0x3f000000)\n"
  99                "       CMPT    %0, #HI(0x02000000)\n"
 100                "       BNZ     1b\n"
 101                : "=&d" (temp), "=&da" (result)
 102                : "da" (&v->counter), "bd" (i)
 103                : "cc");
 104
 105        smp_mb();
 106
 107        return result;
 108}
 109
 110static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
 111{
 112        int temp;
 113
 114        asm volatile (
 115                "1:     LNKGETD %0, [%1]\n"
 116                "       AND     %0, %0, %2\n"
 117                "       LNKSETD [%1] %0\n"
 118                "       DEFR    %0, TXSTAT\n"
 119                "       ANDT    %0, %0, #HI(0x3f000000)\n"
 120                "       CMPT    %0, #HI(0x02000000)\n"
 121                "       BNZ     1b\n"
 122                : "=&d" (temp)
 123                : "da" (&v->counter), "bd" (~mask)
 124                : "cc");
 125}
 126
 127static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
 128{
 129        int temp;
 130
 131        asm volatile (
 132                "1:     LNKGETD %0, [%1]\n"
 133                "       OR      %0, %0, %2\n"
 134                "       LNKSETD [%1], %0\n"
 135                "       DEFR    %0, TXSTAT\n"
 136                "       ANDT    %0, %0, #HI(0x3f000000)\n"
 137                "       CMPT    %0, #HI(0x02000000)\n"
 138                "       BNZ     1b\n"
 139                : "=&d" (temp)
 140                : "da" (&v->counter), "bd" (mask)
 141                : "cc");
 142}
 143
 144static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
 145{
 146        int result, temp;
 147
 148        smp_mb();
 149
 150        asm volatile (
 151                "1:     LNKGETD %1, [%2]\n"
 152                "       CMP     %1, %3\n"
 153                "       LNKSETDEQ [%2], %4\n"
 154                "       BNE     2f\n"
 155                "       DEFR    %0, TXSTAT\n"
 156                "       ANDT    %0, %0, #HI(0x3f000000)\n"
 157                "       CMPT    %0, #HI(0x02000000)\n"
 158                "       BNZ     1b\n"
 159                "2:\n"
 160                : "=&d" (temp), "=&d" (result)
 161                : "da" (&v->counter), "bd" (old), "da" (new)
 162                : "cc");
 163
 164        smp_mb();
 165
 166        return result;
 167}
 168
 169static inline int atomic_xchg(atomic_t *v, int new)
 170{
 171        int temp, old;
 172
 173        asm volatile (
 174                "1:     LNKGETD %1, [%2]\n"
 175                "       LNKSETD [%2], %3\n"
 176                "       DEFR    %0, TXSTAT\n"
 177                "       ANDT    %0, %0, #HI(0x3f000000)\n"
 178                "       CMPT    %0, #HI(0x02000000)\n"
 179                "       BNZ     1b\n"
 180                : "=&d" (temp), "=&d" (old)
 181                : "da" (&v->counter), "da" (new)
 182                : "cc");
 183
 184        return old;
 185}
 186
 187static inline int __atomic_add_unless(atomic_t *v, int a, int u)
 188{
 189        int result, temp;
 190
 191        smp_mb();
 192
 193        asm volatile (
 194                "1:     LNKGETD %1, [%2]\n"
 195                "       CMP     %1, %3\n"
 196                "       ADD     %0, %1, %4\n"
 197                "       LNKSETDNE [%2], %0\n"
 198                "       BEQ     2f\n"
 199                "       DEFR    %0, TXSTAT\n"
 200                "       ANDT    %0, %0, #HI(0x3f000000)\n"
 201                "       CMPT    %0, #HI(0x02000000)\n"
 202                "       BNZ     1b\n"
 203                "2:\n"
 204                : "=&d" (temp), "=&d" (result)
 205                : "da" (&v->counter), "bd" (u), "bd" (a)
 206                : "cc");
 207
 208        smp_mb();
 209
 210        return result;
 211}
 212
 213static inline int atomic_sub_if_positive(int i, atomic_t *v)
 214{
 215        int result, temp;
 216
 217        asm volatile (
 218                "1:     LNKGETD %1, [%2]\n"
 219                "       SUBS    %1, %1, %3\n"
 220                "       LNKSETDGE [%2], %1\n"
 221                "       BLT     2f\n"
 222                "       DEFR    %0, TXSTAT\n"
 223                "       ANDT    %0, %0, #HI(0x3f000000)\n"
 224                "       CMPT    %0, #HI(0x02000000)\n"
 225                "       BNZ     1b\n"
 226                "2:\n"
 227                : "=&d" (temp), "=&da" (result)
 228                : "da" (&v->counter), "bd" (i)
 229                : "cc");
 230
 231        return result;
 232}
 233
 234#endif /* __ASM_METAG_ATOMIC_LNKGET_H */
 235