linux/arch/csky/include/asm/cmpxchg.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2
   3#ifndef __ASM_CSKY_CMPXCHG_H
   4#define __ASM_CSKY_CMPXCHG_H
   5
   6#ifdef CONFIG_CPU_HAS_LDSTEX
   7#include <asm/barrier.h>
   8
   9extern void __bad_xchg(void);
  10
  11#define __xchg(new, ptr, size)                                  \
  12({                                                              \
  13        __typeof__(ptr) __ptr = (ptr);                          \
  14        __typeof__(new) __new = (new);                          \
  15        __typeof__(*(ptr)) __ret;                               \
  16        unsigned long tmp;                                      \
  17        switch (size) {                                         \
  18        case 4:                                                 \
  19                smp_mb();                                       \
  20                asm volatile (                                  \
  21                "1:     ldex.w          %0, (%3) \n"            \
  22                "       mov             %1, %2   \n"            \
  23                "       stex.w          %1, (%3) \n"            \
  24                "       bez             %1, 1b   \n"            \
  25                        : "=&r" (__ret), "=&r" (tmp)            \
  26                        : "r" (__new), "r"(__ptr)               \
  27                        :);                                     \
  28                smp_mb();                                       \
  29                break;                                          \
  30        default:                                                \
  31                __bad_xchg();                                   \
  32        }                                                       \
  33        __ret;                                                  \
  34})
  35
  36#define xchg(ptr, x)    (__xchg((x), (ptr), sizeof(*(ptr))))
  37
  38#define __cmpxchg(ptr, old, new, size)                          \
  39({                                                              \
  40        __typeof__(ptr) __ptr = (ptr);                          \
  41        __typeof__(new) __new = (new);                          \
  42        __typeof__(new) __tmp;                                  \
  43        __typeof__(old) __old = (old);                          \
  44        __typeof__(*(ptr)) __ret;                               \
  45        switch (size) {                                         \
  46        case 4:                                                 \
  47                smp_mb();                                       \
  48                asm volatile (                                  \
  49                "1:     ldex.w          %0, (%3) \n"            \
  50                "       cmpne           %0, %4   \n"            \
  51                "       bt              2f       \n"            \
  52                "       mov             %1, %2   \n"            \
  53                "       stex.w          %1, (%3) \n"            \
  54                "       bez             %1, 1b   \n"            \
  55                "2:                              \n"            \
  56                        : "=&r" (__ret), "=&r" (__tmp)          \
  57                        : "r" (__new), "r"(__ptr), "r"(__old)   \
  58                        :);                                     \
  59                smp_mb();                                       \
  60                break;                                          \
  61        default:                                                \
  62                __bad_xchg();                                   \
  63        }                                                       \
  64        __ret;                                                  \
  65})
  66
  67#define cmpxchg(ptr, o, n) \
  68        (__cmpxchg((ptr), (o), (n), sizeof(*(ptr))))
  69#else
  70#include <asm-generic/cmpxchg.h>
  71#endif
  72
  73#endif /* __ASM_CSKY_CMPXCHG_H */
  74