linux/arch/sh/include/asm/bitops-cas.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef __ASM_SH_BITOPS_CAS_H
   3#define __ASM_SH_BITOPS_CAS_H
   4
   5static inline unsigned __bo_cas(volatile unsigned *p, unsigned old, unsigned new)
   6{
   7        __asm__ __volatile__("cas.l %1,%0,@r0"
   8                : "+r"(new)
   9                : "r"(old), "z"(p)
  10                : "t", "memory" );
  11        return new;
  12}
  13
  14static inline void set_bit(int nr, volatile void *addr)
  15{
  16        unsigned mask, old;
  17        volatile unsigned *a = addr;
  18
  19        a += nr >> 5;
  20        mask = 1U << (nr & 0x1f);
  21
  22        do old = *a;
  23        while (__bo_cas(a, old, old|mask) != old);
  24}
  25
  26static inline void clear_bit(int nr, volatile void *addr)
  27{
  28        unsigned mask, old;
  29        volatile unsigned *a = addr;
  30
  31        a += nr >> 5;
  32        mask = 1U << (nr & 0x1f);
  33
  34        do old = *a;
  35        while (__bo_cas(a, old, old&~mask) != old);
  36}
  37
  38static inline void change_bit(int nr, volatile void *addr)
  39{
  40        unsigned mask, old;
  41        volatile unsigned *a = addr;
  42
  43        a += nr >> 5;
  44        mask = 1U << (nr & 0x1f);
  45
  46        do old = *a;
  47        while (__bo_cas(a, old, old^mask) != old);
  48}
  49
  50static inline int test_and_set_bit(int nr, volatile void *addr)
  51{
  52        unsigned mask, old;
  53        volatile unsigned *a = addr;
  54
  55        a += nr >> 5;
  56        mask = 1U << (nr & 0x1f);
  57
  58        do old = *a;
  59        while (__bo_cas(a, old, old|mask) != old);
  60
  61        return !!(old & mask);
  62}
  63
  64static inline int test_and_clear_bit(int nr, volatile void *addr)
  65{
  66        unsigned mask, old;
  67        volatile unsigned *a = addr;
  68
  69        a += nr >> 5;
  70        mask = 1U << (nr & 0x1f);
  71
  72        do old = *a;
  73        while (__bo_cas(a, old, old&~mask) != old);
  74
  75        return !!(old & mask);
  76}
  77
  78static inline int test_and_change_bit(int nr, volatile void *addr)
  79{
  80        unsigned mask, old;
  81        volatile unsigned *a = addr;
  82
  83        a += nr >> 5;
  84        mask = 1U << (nr & 0x1f);
  85
  86        do old = *a;
  87        while (__bo_cas(a, old, old^mask) != old);
  88
  89        return !!(old & mask);
  90}
  91
  92#include <asm-generic/bitops/non-atomic.h>
  93
  94#endif /* __ASM_SH_BITOPS_CAS_H */
  95