linux/arch/h8300/include/asm/bitops.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _H8300_BITOPS_H
   3#define _H8300_BITOPS_H
   4
   5/*
   6 * Copyright 1992, Linus Torvalds.
   7 * Copyright 2002, Yoshinori Sato
   8 */
   9
  10#include <linux/compiler.h>
  11
  12#ifdef __KERNEL__
  13
  14#ifndef _LINUX_BITOPS_H
  15#error only <linux/bitops.h> can be included directly
  16#endif
  17
  18/*
  19 * Function prototypes to keep gcc -Wall happy
  20 */
  21
  22/*
  23 * ffz = Find First Zero in word. Undefined if no zero exists,
  24 * so code should check against ~0UL first..
  25 */
  26static inline unsigned long ffz(unsigned long word)
  27{
  28        unsigned long result;
  29
  30        result = -1;
  31        __asm__("1:\n\t"
  32                "shlr.l %1\n\t"
  33                "adds #1,%0\n\t"
  34                "bcs 1b"
  35                : "=r"(result),"=r"(word)
  36                : "0"(result), "1"(word));
  37        return result;
  38}
  39
  40#define H8300_GEN_BITOP(FNAME, OP)                              \
  41static inline void FNAME(int nr, volatile unsigned long *addr)  \
  42{                                                               \
  43        unsigned char *b_addr;                                  \
  44        unsigned char bit = nr & 7;                             \
  45                                                                \
  46        b_addr = (unsigned char *)addr + ((nr >> 3) ^ 3);       \
  47        if (__builtin_constant_p(nr)) {                         \
  48                __asm__(OP " %1,%0" : "+WU"(*b_addr) : "i"(nr & 7));    \
  49        } else {                                                \
  50                __asm__(OP " %s1,%0" : "+WU"(*b_addr) : "r"(bit));      \
  51        }                                                       \
  52}
  53
  54/*
  55 * clear_bit() doesn't provide any barrier for the compiler.
  56 */
  57#define smp_mb__before_clear_bit()      barrier()
  58#define smp_mb__after_clear_bit()       barrier()
  59
  60H8300_GEN_BITOP(set_bit,    "bset")
  61H8300_GEN_BITOP(clear_bit,  "bclr")
  62H8300_GEN_BITOP(change_bit, "bnot")
  63#define __set_bit(nr, addr)    set_bit((nr), (addr))
  64#define __clear_bit(nr, addr)  clear_bit((nr), (addr))
  65#define __change_bit(nr, addr) change_bit((nr), (addr))
  66
  67#undef H8300_GEN_BITOP
  68
  69static inline int test_bit(int nr, const volatile unsigned long *addr)
  70{
  71        int ret = 0;
  72        unsigned char *b_addr;
  73        unsigned char bit = nr & 7;
  74
  75        b_addr = (unsigned char *)addr + ((nr >> 3) ^ 3);
  76        if (__builtin_constant_p(nr)) {
  77                __asm__("bld %Z2,%1\n\t"
  78                        "rotxl %0\n\t"
  79                        : "=r"(ret)
  80                        : "WU"(*b_addr), "i"(nr & 7), "0"(ret) : "cc");
  81        } else {
  82                __asm__("btst %w2,%1\n\t"
  83                        "beq 1f\n\t"
  84                        "inc.l #1,%0\n"
  85                        "1:"
  86                        : "=r"(ret)
  87                        : "WU"(*b_addr), "r"(bit), "0"(ret) : "cc");
  88        }
  89        return ret;
  90}
  91
  92#define __test_bit(nr, addr) test_bit(nr, addr)
  93
  94#define H8300_GEN_TEST_BITOP(FNNAME, OP)                                \
  95static inline int FNNAME(int nr, void *addr)                            \
  96{                                                                       \
  97        int retval = 0;                                                 \
  98        char ccrsave;                                                   \
  99        unsigned char *b_addr;                                          \
 100        unsigned char bit = nr & 7;                                     \
 101                                                                        \
 102        b_addr = (unsigned char *)addr + ((nr >> 3) ^ 3);               \
 103        if (__builtin_constant_p(nr)) {                                 \
 104                __asm__("stc ccr,%s2\n\t"                               \
 105                        "orc #0x80,ccr\n\t"                             \
 106                        "bld %4,%1\n\t"                                 \
 107                        OP " %4,%1\n\t"                                 \
 108                        "rotxl.l %0\n\t"                                \
 109                        "ldc %s2,ccr"                                   \
 110                        : "=r"(retval), "+WU" (*b_addr), "=&r"(ccrsave) \
 111                        : "0"(retval), "i"(nr & 7) : "cc");             \
 112        } else {                                                        \
 113                __asm__("stc ccr,%t3\n\t"                               \
 114                        "orc #0x80,ccr\n\t"                             \
 115                        "btst %s3,%1\n\t"                               \
 116                        OP " %s3,%1\n\t"                                \
 117                        "beq 1f\n\t"                                    \
 118                        "inc.l #1,%0\n\t"                               \
 119                        "1:\n"                                          \
 120                        "ldc %t3,ccr"                                   \
 121                        : "=r"(retval), "+WU" (*b_addr)                 \
 122                        : "0" (retval), "r"(bit) : "cc");               \
 123        }                                                               \
 124        return retval;                                                  \
 125}                                                                       \
 126                                                                        \
 127static inline int __ ## FNNAME(int nr, void *addr)                      \
 128{                                                                       \
 129        int retval = 0;                                                 \
 130        unsigned char *b_addr;                                          \
 131        unsigned char bit = nr & 7;                                     \
 132                                                                        \
 133        b_addr = (unsigned char *)addr + ((nr >> 3) ^ 3);               \
 134        if (__builtin_constant_p(nr)) {                                 \
 135                __asm__("bld %3,%1\n\t"                                 \
 136                        OP " %3,%1\n\t"                                 \
 137                        "rotxl.l %0\n\t"                                \
 138                        : "=r"(retval), "+WU"(*b_addr)                  \
 139                        : "0" (retval), "i"(nr & 7));                   \
 140        } else {                                                        \
 141                __asm__("btst %s3,%1\n\t"                               \
 142                        OP " %s3,%1\n\t"                                \
 143                        "beq 1f\n\t"                                    \
 144                        "inc.l #1,%0\n\t"                               \
 145                        "1:"                                            \
 146                        : "=r"(retval), "+WU"(*b_addr)                  \
 147                        : "0" (retval), "r"(bit));                      \
 148        }                                                               \
 149        return retval;                                                  \
 150}
 151
 152H8300_GEN_TEST_BITOP(test_and_set_bit,    "bset")
 153H8300_GEN_TEST_BITOP(test_and_clear_bit,  "bclr")
 154H8300_GEN_TEST_BITOP(test_and_change_bit, "bnot")
 155#undef H8300_GEN_TEST_BITOP
 156
 157#include <asm-generic/bitops/ffs.h>
 158
 159static inline unsigned long __ffs(unsigned long word)
 160{
 161        unsigned long result;
 162
 163        result = -1;
 164        __asm__("1:\n\t"
 165                "shlr.l %1\n\t"
 166                "adds #1,%0\n\t"
 167                "bcc 1b"
 168                : "=r" (result),"=r"(word)
 169                : "0"(result), "1"(word));
 170        return result;
 171}
 172
 173#include <asm-generic/bitops/find.h>
 174#include <asm-generic/bitops/sched.h>
 175#include <asm-generic/bitops/hweight.h>
 176#include <asm-generic/bitops/lock.h>
 177#include <asm-generic/bitops/le.h>
 178#include <asm-generic/bitops/ext2-atomic.h>
 179
 180#endif /* __KERNEL__ */
 181
 182#include <asm-generic/bitops/fls.h>
 183#include <asm-generic/bitops/__fls.h>
 184#include <asm-generic/bitops/fls64.h>
 185
 186#endif /* _H8300_BITOPS_H */
 187