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