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
  54H8300_GEN_BITOP(set_bit,    "bset")
  55H8300_GEN_BITOP(clear_bit,  "bclr")
  56H8300_GEN_BITOP(change_bit, "bnot")
  57#define __set_bit(nr, addr)    set_bit((nr), (addr))
  58#define __clear_bit(nr, addr)  clear_bit((nr), (addr))
  59#define __change_bit(nr, addr) change_bit((nr), (addr))
  60
  61#undef H8300_GEN_BITOP
  62
  63static inline int test_bit(int nr, const volatile unsigned long *addr)
  64{
  65        int ret = 0;
  66        unsigned char *b_addr;
  67        unsigned char bit = nr & 7;
  68
  69        b_addr = (unsigned char *)addr + ((nr >> 3) ^ 3);
  70        if (__builtin_constant_p(nr)) {
  71                __asm__("bld %Z2,%1\n\t"
  72                        "rotxl %0\n\t"
  73                        : "=r"(ret)
  74                        : "WU"(*b_addr), "i"(nr & 7), "0"(ret) : "cc");
  75        } else {
  76                __asm__("btst %w2,%1\n\t"
  77                        "beq 1f\n\t"
  78                        "inc.l #1,%0\n"
  79                        "1:"
  80                        : "=r"(ret)
  81                        : "WU"(*b_addr), "r"(bit), "0"(ret) : "cc");
  82        }
  83        return ret;
  84}
  85
  86#define __test_bit(nr, addr) test_bit(nr, addr)
  87
  88#define H8300_GEN_TEST_BITOP(FNNAME, OP)                                \
  89static inline int FNNAME(int nr, void *addr)                            \
  90{                                                                       \
  91        int retval = 0;                                                 \
  92        char ccrsave;                                                   \
  93        unsigned char *b_addr;                                          \
  94        unsigned char bit = nr & 7;                                     \
  95                                                                        \
  96        b_addr = (unsigned char *)addr + ((nr >> 3) ^ 3);               \
  97        if (__builtin_constant_p(nr)) {                                 \
  98                __asm__("stc ccr,%s2\n\t"                               \
  99                        "orc #0x80,ccr\n\t"                             \
 100                        "bld %4,%1\n\t"                                 \
 101                        OP " %4,%1\n\t"                                 \
 102                        "rotxl.l %0\n\t"                                \
 103                        "ldc %s2,ccr"                                   \
 104                        : "=r"(retval), "+WU" (*b_addr), "=&r"(ccrsave) \
 105                        : "0"(retval), "i"(nr & 7) : "cc");             \
 106        } else {                                                        \
 107                __asm__("stc ccr,%t3\n\t"                               \
 108                        "orc #0x80,ccr\n\t"                             \
 109                        "btst %s3,%1\n\t"                               \
 110                        OP " %s3,%1\n\t"                                \
 111                        "beq 1f\n\t"                                    \
 112                        "inc.l #1,%0\n\t"                               \
 113                        "1:\n"                                          \
 114                        "ldc %t3,ccr"                                   \
 115                        : "=r"(retval), "+WU" (*b_addr)                 \
 116                        : "0" (retval), "r"(bit) : "cc");               \
 117        }                                                               \
 118        return retval;                                                  \
 119}                                                                       \
 120                                                                        \
 121static inline int __ ## FNNAME(int nr, void *addr)                      \
 122{                                                                       \
 123        int retval = 0;                                                 \
 124        unsigned char *b_addr;                                          \
 125        unsigned char bit = nr & 7;                                     \
 126                                                                        \
 127        b_addr = (unsigned char *)addr + ((nr >> 3) ^ 3);               \
 128        if (__builtin_constant_p(nr)) {                                 \
 129                __asm__("bld %3,%1\n\t"                                 \
 130                        OP " %3,%1\n\t"                                 \
 131                        "rotxl.l %0\n\t"                                \
 132                        : "=r"(retval), "+WU"(*b_addr)                  \
 133                        : "0" (retval), "i"(nr & 7));                   \
 134        } else {                                                        \
 135                __asm__("btst %s3,%1\n\t"                               \
 136                        OP " %s3,%1\n\t"                                \
 137                        "beq 1f\n\t"                                    \
 138                        "inc.l #1,%0\n\t"                               \
 139                        "1:"                                            \
 140                        : "=r"(retval), "+WU"(*b_addr)                  \
 141                        : "0" (retval), "r"(bit));                      \
 142        }                                                               \
 143        return retval;                                                  \
 144}
 145
 146H8300_GEN_TEST_BITOP(test_and_set_bit,    "bset")
 147H8300_GEN_TEST_BITOP(test_and_clear_bit,  "bclr")
 148H8300_GEN_TEST_BITOP(test_and_change_bit, "bnot")
 149#undef H8300_GEN_TEST_BITOP
 150
 151#include <asm-generic/bitops/ffs.h>
 152
 153static inline unsigned long __ffs(unsigned long word)
 154{
 155        unsigned long result;
 156
 157        result = -1;
 158        __asm__("1:\n\t"
 159                "shlr.l %1\n\t"
 160                "adds #1,%0\n\t"
 161                "bcc 1b"
 162                : "=r" (result),"=r"(word)
 163                : "0"(result), "1"(word));
 164        return result;
 165}
 166
 167#include <asm-generic/bitops/find.h>
 168#include <asm-generic/bitops/sched.h>
 169#include <asm-generic/bitops/hweight.h>
 170#include <asm-generic/bitops/lock.h>
 171#include <asm-generic/bitops/le.h>
 172#include <asm-generic/bitops/ext2-atomic.h>
 173
 174#endif /* __KERNEL__ */
 175
 176#include <asm-generic/bitops/fls.h>
 177#include <asm-generic/bitops/__fls.h>
 178#include <asm-generic/bitops/fls64.h>
 179
 180#endif /* _H8300_BITOPS_H */
 181