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