1#ifndef _H8300_BITOPS_H 2#define _H8300_BITOPS_H 3 4/* 5 * Copyright 1992, Linus Torvalds. 6 * Copyright 2002, Yoshinori Sato 7 */ 8 9#include <linux/compiler.h> 10#include <asm/system.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 %2\n\t" 33 "adds #1,%0\n\t" 34 "bcs 1b" 35 : "=r" (result) 36 : "0" (result),"r" (word)); 37 return result; 38} 39 40#define H8300_GEN_BITOP_CONST(OP,BIT) \ 41 case BIT: \ 42 __asm__(OP " #" #BIT ",@%0"::"r"(b_addr):"memory"); \ 43 break; 44 45#define H8300_GEN_BITOP(FNAME,OP) \ 46static __inline__ void FNAME(int nr, volatile unsigned long* addr) \ 47{ \ 48 volatile unsigned char *b_addr; \ 49 b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3); \ 50 if (__builtin_constant_p(nr)) { \ 51 switch(nr & 7) { \ 52 H8300_GEN_BITOP_CONST(OP,0) \ 53 H8300_GEN_BITOP_CONST(OP,1) \ 54 H8300_GEN_BITOP_CONST(OP,2) \ 55 H8300_GEN_BITOP_CONST(OP,3) \ 56 H8300_GEN_BITOP_CONST(OP,4) \ 57 H8300_GEN_BITOP_CONST(OP,5) \ 58 H8300_GEN_BITOP_CONST(OP,6) \ 59 H8300_GEN_BITOP_CONST(OP,7) \ 60 } \ 61 } else { \ 62 __asm__(OP " %w0,@%1"::"r"(nr),"r"(b_addr):"memory"); \ 63 } \ 64} 65 66/* 67 * clear_bit() doesn't provide any barrier for the compiler. 68 */ 69#define smp_mb__before_clear_bit() barrier() 70#define smp_mb__after_clear_bit() barrier() 71 72H8300_GEN_BITOP(set_bit ,"bset") 73H8300_GEN_BITOP(clear_bit ,"bclr") 74H8300_GEN_BITOP(change_bit,"bnot") 75#define __set_bit(nr,addr) set_bit((nr),(addr)) 76#define __clear_bit(nr,addr) clear_bit((nr),(addr)) 77#define __change_bit(nr,addr) change_bit((nr),(addr)) 78 79#undef H8300_GEN_BITOP 80#undef H8300_GEN_BITOP_CONST 81 82static __inline__ int test_bit(int nr, const unsigned long* addr) 83{ 84 return (*((volatile unsigned char *)addr + 85 ((nr >> 3) ^ 3)) & (1UL << (nr & 7))) != 0; 86} 87 88#define __test_bit(nr, addr) test_bit(nr, addr) 89 90#define H8300_GEN_TEST_BITOP_CONST_INT(OP,BIT) \ 91 case BIT: \ 92 __asm__("stc ccr,%w1\n\t" \ 93 "orc #0x80,ccr\n\t" \ 94 "bld #" #BIT ",@%4\n\t" \ 95 OP " #" #BIT ",@%4\n\t" \ 96 "rotxl.l %0\n\t" \ 97 "ldc %w1,ccr" \ 98 : "=r"(retval),"=&r"(ccrsave),"=m"(*b_addr) \ 99 : "0" (retval),"r" (b_addr) \ 100 : "memory"); \ 101 break; 102 103#define H8300_GEN_TEST_BITOP_CONST(OP,BIT) \ 104 case BIT: \ 105 __asm__("bld #" #BIT ",@%3\n\t" \ 106 OP " #" #BIT ",@%3\n\t" \ 107 "rotxl.l %0\n\t" \ 108 : "=r"(retval),"=m"(*b_addr) \ 109 : "0" (retval),"r" (b_addr) \ 110 : "memory"); \ 111 break; 112 113#define H8300_GEN_TEST_BITOP(FNNAME,OP) \ 114static __inline__ int FNNAME(int nr, volatile void * addr) \ 115{ \ 116 int retval = 0; \ 117 char ccrsave; \ 118 volatile unsigned char *b_addr; \ 119 b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3); \ 120 if (__builtin_constant_p(nr)) { \ 121 switch(nr & 7) { \ 122 H8300_GEN_TEST_BITOP_CONST_INT(OP,0) \ 123 H8300_GEN_TEST_BITOP_CONST_INT(OP,1) \ 124 H8300_GEN_TEST_BITOP_CONST_INT(OP,2) \ 125 H8300_GEN_TEST_BITOP_CONST_INT(OP,3) \ 126 H8300_GEN_TEST_BITOP_CONST_INT(OP,4) \ 127 H8300_GEN_TEST_BITOP_CONST_INT(OP,5) \ 128 H8300_GEN_TEST_BITOP_CONST_INT(OP,6) \ 129 H8300_GEN_TEST_BITOP_CONST_INT(OP,7) \ 130 } \ 131 } else { \ 132 __asm__("stc ccr,%w1\n\t" \ 133 "orc #0x80,ccr\n\t" \ 134 "btst %w5,@%4\n\t" \ 135 OP " %w5,@%4\n\t" \ 136 "beq 1f\n\t" \ 137 "inc.l #1,%0\n" \ 138 "1:\n\t" \ 139 "ldc %w1,ccr" \ 140 : "=r"(retval),"=&r"(ccrsave),"=m"(*b_addr) \ 141 : "0" (retval),"r" (b_addr),"r"(nr) \ 142 : "memory"); \ 143 } \ 144 return retval; \ 145} \ 146 \ 147static __inline__ int __ ## FNNAME(int nr, volatile void * addr) \ 148{ \ 149 int retval = 0; \ 150 volatile unsigned char *b_addr; \ 151 b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3); \ 152 if (__builtin_constant_p(nr)) { \ 153 switch(nr & 7) { \ 154 H8300_GEN_TEST_BITOP_CONST(OP,0) \ 155 H8300_GEN_TEST_BITOP_CONST(OP,1) \ 156 H8300_GEN_TEST_BITOP_CONST(OP,2) \ 157 H8300_GEN_TEST_BITOP_CONST(OP,3) \ 158 H8300_GEN_TEST_BITOP_CONST(OP,4) \ 159 H8300_GEN_TEST_BITOP_CONST(OP,5) \ 160 H8300_GEN_TEST_BITOP_CONST(OP,6) \ 161 H8300_GEN_TEST_BITOP_CONST(OP,7) \ 162 } \ 163 } else { \ 164 __asm__("btst %w4,@%3\n\t" \ 165 OP " %w4,@%3\n\t" \ 166 "beq 1f\n\t" \ 167 "inc.l #1,%0\n" \ 168 "1:" \ 169 : "=r"(retval),"=m"(*b_addr) \ 170 : "0" (retval),"r" (b_addr),"r"(nr) \ 171 : "memory"); \ 172 } \ 173 return retval; \ 174} 175 176H8300_GEN_TEST_BITOP(test_and_set_bit, "bset") 177H8300_GEN_TEST_BITOP(test_and_clear_bit, "bclr") 178H8300_GEN_TEST_BITOP(test_and_change_bit,"bnot") 179#undef H8300_GEN_TEST_BITOP_CONST 180#undef H8300_GEN_TEST_BITOP_CONST_INT 181#undef H8300_GEN_TEST_BITOP 182 183#include <asm-generic/bitops/ffs.h> 184 185static __inline__ unsigned long __ffs(unsigned long word) 186{ 187 unsigned long result; 188 189 result = -1; 190 __asm__("1:\n\t" 191 "shlr.l %2\n\t" 192 "adds #1,%0\n\t" 193 "bcc 1b" 194 : "=r" (result) 195 : "0"(result),"r"(word)); 196 return result; 197} 198 199#include <asm-generic/bitops/find.h> 200#include <asm-generic/bitops/sched.h> 201#include <asm-generic/bitops/hweight.h> 202#include <asm-generic/bitops/lock.h> 203#include <asm-generic/bitops/ext2-non-atomic.h> 204#include <asm-generic/bitops/ext2-atomic.h> 205#include <asm-generic/bitops/minix.h> 206 207#endif /* __KERNEL__ */ 208 209#include <asm-generic/bitops/fls.h> 210#include <asm-generic/bitops/__fls.h> 211#include <asm-generic/bitops/fls64.h> 212 213#endif /* _H8300_BITOPS_H */ 214