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