18c2ecf20Sopenharmony_ci#ifndef _M68K_BITOPS_H 28c2ecf20Sopenharmony_ci#define _M68K_BITOPS_H 38c2ecf20Sopenharmony_ci/* 48c2ecf20Sopenharmony_ci * Copyright 1992, Linus Torvalds. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 78c2ecf20Sopenharmony_ci * License. See the file COPYING in the main directory of this archive 88c2ecf20Sopenharmony_ci * for more details. 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#ifndef _LINUX_BITOPS_H 128c2ecf20Sopenharmony_ci#error only <linux/bitops.h> can be included directly 138c2ecf20Sopenharmony_ci#endif 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <linux/compiler.h> 168c2ecf20Sopenharmony_ci#include <asm/barrier.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci/* 198c2ecf20Sopenharmony_ci * Bit access functions vary across the ColdFire and 68k families. 208c2ecf20Sopenharmony_ci * So we will break them out here, and then macro in the ones we want. 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * ColdFire - supports standard bset/bclr/bchg with register operand only 238c2ecf20Sopenharmony_ci * 68000 - supports standard bset/bclr/bchg with memory operand 248c2ecf20Sopenharmony_ci * >= 68020 - also supports the bfset/bfclr/bfchg instructions 258c2ecf20Sopenharmony_ci * 268c2ecf20Sopenharmony_ci * Although it is possible to use only the bset/bclr/bchg with register 278c2ecf20Sopenharmony_ci * operands on all platforms you end up with larger generated code. 288c2ecf20Sopenharmony_ci * So we use the best form possible on a given platform. 298c2ecf20Sopenharmony_ci */ 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cistatic inline void bset_reg_set_bit(int nr, volatile unsigned long *vaddr) 328c2ecf20Sopenharmony_ci{ 338c2ecf20Sopenharmony_ci char *p = (char *)vaddr + (nr ^ 31) / 8; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bset %1,(%0)" 368c2ecf20Sopenharmony_ci : 378c2ecf20Sopenharmony_ci : "a" (p), "di" (nr & 7) 388c2ecf20Sopenharmony_ci : "memory"); 398c2ecf20Sopenharmony_ci} 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic inline void bset_mem_set_bit(int nr, volatile unsigned long *vaddr) 428c2ecf20Sopenharmony_ci{ 438c2ecf20Sopenharmony_ci char *p = (char *)vaddr + (nr ^ 31) / 8; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bset %1,%0" 468c2ecf20Sopenharmony_ci : "+m" (*p) 478c2ecf20Sopenharmony_ci : "di" (nr & 7)); 488c2ecf20Sopenharmony_ci} 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistatic inline void bfset_mem_set_bit(int nr, volatile unsigned long *vaddr) 518c2ecf20Sopenharmony_ci{ 528c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bfset %1{%0:#1}" 538c2ecf20Sopenharmony_ci : 548c2ecf20Sopenharmony_ci : "d" (nr ^ 31), "o" (*vaddr) 558c2ecf20Sopenharmony_ci : "memory"); 568c2ecf20Sopenharmony_ci} 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci#if defined(CONFIG_COLDFIRE) 598c2ecf20Sopenharmony_ci#define set_bit(nr, vaddr) bset_reg_set_bit(nr, vaddr) 608c2ecf20Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS) 618c2ecf20Sopenharmony_ci#define set_bit(nr, vaddr) bset_mem_set_bit(nr, vaddr) 628c2ecf20Sopenharmony_ci#else 638c2ecf20Sopenharmony_ci#define set_bit(nr, vaddr) (__builtin_constant_p(nr) ? \ 648c2ecf20Sopenharmony_ci bset_mem_set_bit(nr, vaddr) : \ 658c2ecf20Sopenharmony_ci bfset_mem_set_bit(nr, vaddr)) 668c2ecf20Sopenharmony_ci#endif 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci#define __set_bit(nr, vaddr) set_bit(nr, vaddr) 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistatic inline void bclr_reg_clear_bit(int nr, volatile unsigned long *vaddr) 728c2ecf20Sopenharmony_ci{ 738c2ecf20Sopenharmony_ci char *p = (char *)vaddr + (nr ^ 31) / 8; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bclr %1,(%0)" 768c2ecf20Sopenharmony_ci : 778c2ecf20Sopenharmony_ci : "a" (p), "di" (nr & 7) 788c2ecf20Sopenharmony_ci : "memory"); 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistatic inline void bclr_mem_clear_bit(int nr, volatile unsigned long *vaddr) 828c2ecf20Sopenharmony_ci{ 838c2ecf20Sopenharmony_ci char *p = (char *)vaddr + (nr ^ 31) / 8; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bclr %1,%0" 868c2ecf20Sopenharmony_ci : "+m" (*p) 878c2ecf20Sopenharmony_ci : "di" (nr & 7)); 888c2ecf20Sopenharmony_ci} 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_cistatic inline void bfclr_mem_clear_bit(int nr, volatile unsigned long *vaddr) 918c2ecf20Sopenharmony_ci{ 928c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bfclr %1{%0:#1}" 938c2ecf20Sopenharmony_ci : 948c2ecf20Sopenharmony_ci : "d" (nr ^ 31), "o" (*vaddr) 958c2ecf20Sopenharmony_ci : "memory"); 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci#if defined(CONFIG_COLDFIRE) 998c2ecf20Sopenharmony_ci#define clear_bit(nr, vaddr) bclr_reg_clear_bit(nr, vaddr) 1008c2ecf20Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS) 1018c2ecf20Sopenharmony_ci#define clear_bit(nr, vaddr) bclr_mem_clear_bit(nr, vaddr) 1028c2ecf20Sopenharmony_ci#else 1038c2ecf20Sopenharmony_ci#define clear_bit(nr, vaddr) (__builtin_constant_p(nr) ? \ 1048c2ecf20Sopenharmony_ci bclr_mem_clear_bit(nr, vaddr) : \ 1058c2ecf20Sopenharmony_ci bfclr_mem_clear_bit(nr, vaddr)) 1068c2ecf20Sopenharmony_ci#endif 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci#define __clear_bit(nr, vaddr) clear_bit(nr, vaddr) 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_cistatic inline void bchg_reg_change_bit(int nr, volatile unsigned long *vaddr) 1128c2ecf20Sopenharmony_ci{ 1138c2ecf20Sopenharmony_ci char *p = (char *)vaddr + (nr ^ 31) / 8; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bchg %1,(%0)" 1168c2ecf20Sopenharmony_ci : 1178c2ecf20Sopenharmony_ci : "a" (p), "di" (nr & 7) 1188c2ecf20Sopenharmony_ci : "memory"); 1198c2ecf20Sopenharmony_ci} 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_cistatic inline void bchg_mem_change_bit(int nr, volatile unsigned long *vaddr) 1228c2ecf20Sopenharmony_ci{ 1238c2ecf20Sopenharmony_ci char *p = (char *)vaddr + (nr ^ 31) / 8; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bchg %1,%0" 1268c2ecf20Sopenharmony_ci : "+m" (*p) 1278c2ecf20Sopenharmony_ci : "di" (nr & 7)); 1288c2ecf20Sopenharmony_ci} 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_cistatic inline void bfchg_mem_change_bit(int nr, volatile unsigned long *vaddr) 1318c2ecf20Sopenharmony_ci{ 1328c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bfchg %1{%0:#1}" 1338c2ecf20Sopenharmony_ci : 1348c2ecf20Sopenharmony_ci : "d" (nr ^ 31), "o" (*vaddr) 1358c2ecf20Sopenharmony_ci : "memory"); 1368c2ecf20Sopenharmony_ci} 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci#if defined(CONFIG_COLDFIRE) 1398c2ecf20Sopenharmony_ci#define change_bit(nr, vaddr) bchg_reg_change_bit(nr, vaddr) 1408c2ecf20Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS) 1418c2ecf20Sopenharmony_ci#define change_bit(nr, vaddr) bchg_mem_change_bit(nr, vaddr) 1428c2ecf20Sopenharmony_ci#else 1438c2ecf20Sopenharmony_ci#define change_bit(nr, vaddr) (__builtin_constant_p(nr) ? \ 1448c2ecf20Sopenharmony_ci bchg_mem_change_bit(nr, vaddr) : \ 1458c2ecf20Sopenharmony_ci bfchg_mem_change_bit(nr, vaddr)) 1468c2ecf20Sopenharmony_ci#endif 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci#define __change_bit(nr, vaddr) change_bit(nr, vaddr) 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_cistatic inline int test_bit(int nr, const volatile unsigned long *vaddr) 1528c2ecf20Sopenharmony_ci{ 1538c2ecf20Sopenharmony_ci return (vaddr[nr >> 5] & (1UL << (nr & 31))) != 0; 1548c2ecf20Sopenharmony_ci} 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_cistatic inline int bset_reg_test_and_set_bit(int nr, 1588c2ecf20Sopenharmony_ci volatile unsigned long *vaddr) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci char *p = (char *)vaddr + (nr ^ 31) / 8; 1618c2ecf20Sopenharmony_ci char retval; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bset %2,(%1); sne %0" 1648c2ecf20Sopenharmony_ci : "=d" (retval) 1658c2ecf20Sopenharmony_ci : "a" (p), "di" (nr & 7) 1668c2ecf20Sopenharmony_ci : "memory"); 1678c2ecf20Sopenharmony_ci return retval; 1688c2ecf20Sopenharmony_ci} 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_cistatic inline int bset_mem_test_and_set_bit(int nr, 1718c2ecf20Sopenharmony_ci volatile unsigned long *vaddr) 1728c2ecf20Sopenharmony_ci{ 1738c2ecf20Sopenharmony_ci char *p = (char *)vaddr + (nr ^ 31) / 8; 1748c2ecf20Sopenharmony_ci char retval; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bset %2,%1; sne %0" 1778c2ecf20Sopenharmony_ci : "=d" (retval), "+m" (*p) 1788c2ecf20Sopenharmony_ci : "di" (nr & 7)); 1798c2ecf20Sopenharmony_ci return retval; 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cistatic inline int bfset_mem_test_and_set_bit(int nr, 1838c2ecf20Sopenharmony_ci volatile unsigned long *vaddr) 1848c2ecf20Sopenharmony_ci{ 1858c2ecf20Sopenharmony_ci char retval; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bfset %2{%1:#1}; sne %0" 1888c2ecf20Sopenharmony_ci : "=d" (retval) 1898c2ecf20Sopenharmony_ci : "d" (nr ^ 31), "o" (*vaddr) 1908c2ecf20Sopenharmony_ci : "memory"); 1918c2ecf20Sopenharmony_ci return retval; 1928c2ecf20Sopenharmony_ci} 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci#if defined(CONFIG_COLDFIRE) 1958c2ecf20Sopenharmony_ci#define test_and_set_bit(nr, vaddr) bset_reg_test_and_set_bit(nr, vaddr) 1968c2ecf20Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS) 1978c2ecf20Sopenharmony_ci#define test_and_set_bit(nr, vaddr) bset_mem_test_and_set_bit(nr, vaddr) 1988c2ecf20Sopenharmony_ci#else 1998c2ecf20Sopenharmony_ci#define test_and_set_bit(nr, vaddr) (__builtin_constant_p(nr) ? \ 2008c2ecf20Sopenharmony_ci bset_mem_test_and_set_bit(nr, vaddr) : \ 2018c2ecf20Sopenharmony_ci bfset_mem_test_and_set_bit(nr, vaddr)) 2028c2ecf20Sopenharmony_ci#endif 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci#define __test_and_set_bit(nr, vaddr) test_and_set_bit(nr, vaddr) 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_cistatic inline int bclr_reg_test_and_clear_bit(int nr, 2088c2ecf20Sopenharmony_ci volatile unsigned long *vaddr) 2098c2ecf20Sopenharmony_ci{ 2108c2ecf20Sopenharmony_ci char *p = (char *)vaddr + (nr ^ 31) / 8; 2118c2ecf20Sopenharmony_ci char retval; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bclr %2,(%1); sne %0" 2148c2ecf20Sopenharmony_ci : "=d" (retval) 2158c2ecf20Sopenharmony_ci : "a" (p), "di" (nr & 7) 2168c2ecf20Sopenharmony_ci : "memory"); 2178c2ecf20Sopenharmony_ci return retval; 2188c2ecf20Sopenharmony_ci} 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_cistatic inline int bclr_mem_test_and_clear_bit(int nr, 2218c2ecf20Sopenharmony_ci volatile unsigned long *vaddr) 2228c2ecf20Sopenharmony_ci{ 2238c2ecf20Sopenharmony_ci char *p = (char *)vaddr + (nr ^ 31) / 8; 2248c2ecf20Sopenharmony_ci char retval; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bclr %2,%1; sne %0" 2278c2ecf20Sopenharmony_ci : "=d" (retval), "+m" (*p) 2288c2ecf20Sopenharmony_ci : "di" (nr & 7)); 2298c2ecf20Sopenharmony_ci return retval; 2308c2ecf20Sopenharmony_ci} 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_cistatic inline int bfclr_mem_test_and_clear_bit(int nr, 2338c2ecf20Sopenharmony_ci volatile unsigned long *vaddr) 2348c2ecf20Sopenharmony_ci{ 2358c2ecf20Sopenharmony_ci char retval; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bfclr %2{%1:#1}; sne %0" 2388c2ecf20Sopenharmony_ci : "=d" (retval) 2398c2ecf20Sopenharmony_ci : "d" (nr ^ 31), "o" (*vaddr) 2408c2ecf20Sopenharmony_ci : "memory"); 2418c2ecf20Sopenharmony_ci return retval; 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci#if defined(CONFIG_COLDFIRE) 2458c2ecf20Sopenharmony_ci#define test_and_clear_bit(nr, vaddr) bclr_reg_test_and_clear_bit(nr, vaddr) 2468c2ecf20Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS) 2478c2ecf20Sopenharmony_ci#define test_and_clear_bit(nr, vaddr) bclr_mem_test_and_clear_bit(nr, vaddr) 2488c2ecf20Sopenharmony_ci#else 2498c2ecf20Sopenharmony_ci#define test_and_clear_bit(nr, vaddr) (__builtin_constant_p(nr) ? \ 2508c2ecf20Sopenharmony_ci bclr_mem_test_and_clear_bit(nr, vaddr) : \ 2518c2ecf20Sopenharmony_ci bfclr_mem_test_and_clear_bit(nr, vaddr)) 2528c2ecf20Sopenharmony_ci#endif 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci#define __test_and_clear_bit(nr, vaddr) test_and_clear_bit(nr, vaddr) 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_cistatic inline int bchg_reg_test_and_change_bit(int nr, 2588c2ecf20Sopenharmony_ci volatile unsigned long *vaddr) 2598c2ecf20Sopenharmony_ci{ 2608c2ecf20Sopenharmony_ci char *p = (char *)vaddr + (nr ^ 31) / 8; 2618c2ecf20Sopenharmony_ci char retval; 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bchg %2,(%1); sne %0" 2648c2ecf20Sopenharmony_ci : "=d" (retval) 2658c2ecf20Sopenharmony_ci : "a" (p), "di" (nr & 7) 2668c2ecf20Sopenharmony_ci : "memory"); 2678c2ecf20Sopenharmony_ci return retval; 2688c2ecf20Sopenharmony_ci} 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_cistatic inline int bchg_mem_test_and_change_bit(int nr, 2718c2ecf20Sopenharmony_ci volatile unsigned long *vaddr) 2728c2ecf20Sopenharmony_ci{ 2738c2ecf20Sopenharmony_ci char *p = (char *)vaddr + (nr ^ 31) / 8; 2748c2ecf20Sopenharmony_ci char retval; 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bchg %2,%1; sne %0" 2778c2ecf20Sopenharmony_ci : "=d" (retval), "+m" (*p) 2788c2ecf20Sopenharmony_ci : "di" (nr & 7)); 2798c2ecf20Sopenharmony_ci return retval; 2808c2ecf20Sopenharmony_ci} 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_cistatic inline int bfchg_mem_test_and_change_bit(int nr, 2838c2ecf20Sopenharmony_ci volatile unsigned long *vaddr) 2848c2ecf20Sopenharmony_ci{ 2858c2ecf20Sopenharmony_ci char retval; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bfchg %2{%1:#1}; sne %0" 2888c2ecf20Sopenharmony_ci : "=d" (retval) 2898c2ecf20Sopenharmony_ci : "d" (nr ^ 31), "o" (*vaddr) 2908c2ecf20Sopenharmony_ci : "memory"); 2918c2ecf20Sopenharmony_ci return retval; 2928c2ecf20Sopenharmony_ci} 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci#if defined(CONFIG_COLDFIRE) 2958c2ecf20Sopenharmony_ci#define test_and_change_bit(nr, vaddr) bchg_reg_test_and_change_bit(nr, vaddr) 2968c2ecf20Sopenharmony_ci#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS) 2978c2ecf20Sopenharmony_ci#define test_and_change_bit(nr, vaddr) bchg_mem_test_and_change_bit(nr, vaddr) 2988c2ecf20Sopenharmony_ci#else 2998c2ecf20Sopenharmony_ci#define test_and_change_bit(nr, vaddr) (__builtin_constant_p(nr) ? \ 3008c2ecf20Sopenharmony_ci bchg_mem_test_and_change_bit(nr, vaddr) : \ 3018c2ecf20Sopenharmony_ci bfchg_mem_test_and_change_bit(nr, vaddr)) 3028c2ecf20Sopenharmony_ci#endif 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci#define __test_and_change_bit(nr, vaddr) test_and_change_bit(nr, vaddr) 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci/* 3088c2ecf20Sopenharmony_ci * The true 68020 and more advanced processors support the "bfffo" 3098c2ecf20Sopenharmony_ci * instruction for finding bits. ColdFire and simple 68000 parts 3108c2ecf20Sopenharmony_ci * (including CPU32) do not support this. They simply use the generic 3118c2ecf20Sopenharmony_ci * functions. 3128c2ecf20Sopenharmony_ci */ 3138c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_HAS_NO_BITFIELDS) 3148c2ecf20Sopenharmony_ci#include <asm-generic/bitops/ffz.h> 3158c2ecf20Sopenharmony_ci#else 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_cistatic inline int find_first_zero_bit(const unsigned long *vaddr, 3188c2ecf20Sopenharmony_ci unsigned size) 3198c2ecf20Sopenharmony_ci{ 3208c2ecf20Sopenharmony_ci const unsigned long *p = vaddr; 3218c2ecf20Sopenharmony_ci int res = 32; 3228c2ecf20Sopenharmony_ci unsigned int words; 3238c2ecf20Sopenharmony_ci unsigned long num; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci if (!size) 3268c2ecf20Sopenharmony_ci return 0; 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci words = (size + 31) >> 5; 3298c2ecf20Sopenharmony_ci while (!(num = ~*p++)) { 3308c2ecf20Sopenharmony_ci if (!--words) 3318c2ecf20Sopenharmony_ci goto out; 3328c2ecf20Sopenharmony_ci } 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 3358c2ecf20Sopenharmony_ci : "=d" (res) : "d" (num & -num)); 3368c2ecf20Sopenharmony_ci res ^= 31; 3378c2ecf20Sopenharmony_ciout: 3388c2ecf20Sopenharmony_ci res += ((long)p - (long)vaddr - 4) * 8; 3398c2ecf20Sopenharmony_ci return res < size ? res : size; 3408c2ecf20Sopenharmony_ci} 3418c2ecf20Sopenharmony_ci#define find_first_zero_bit find_first_zero_bit 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_cistatic inline int find_next_zero_bit(const unsigned long *vaddr, int size, 3448c2ecf20Sopenharmony_ci int offset) 3458c2ecf20Sopenharmony_ci{ 3468c2ecf20Sopenharmony_ci const unsigned long *p = vaddr + (offset >> 5); 3478c2ecf20Sopenharmony_ci int bit = offset & 31UL, res; 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_ci if (offset >= size) 3508c2ecf20Sopenharmony_ci return size; 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci if (bit) { 3538c2ecf20Sopenharmony_ci unsigned long num = ~*p++ & (~0UL << bit); 3548c2ecf20Sopenharmony_ci offset -= bit; 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci /* Look for zero in first longword */ 3578c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 3588c2ecf20Sopenharmony_ci : "=d" (res) : "d" (num & -num)); 3598c2ecf20Sopenharmony_ci if (res < 32) { 3608c2ecf20Sopenharmony_ci offset += res ^ 31; 3618c2ecf20Sopenharmony_ci return offset < size ? offset : size; 3628c2ecf20Sopenharmony_ci } 3638c2ecf20Sopenharmony_ci offset += 32; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci if (offset >= size) 3668c2ecf20Sopenharmony_ci return size; 3678c2ecf20Sopenharmony_ci } 3688c2ecf20Sopenharmony_ci /* No zero yet, search remaining full bytes for a zero */ 3698c2ecf20Sopenharmony_ci return offset + find_first_zero_bit(p, size - offset); 3708c2ecf20Sopenharmony_ci} 3718c2ecf20Sopenharmony_ci#define find_next_zero_bit find_next_zero_bit 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_cistatic inline int find_first_bit(const unsigned long *vaddr, unsigned size) 3748c2ecf20Sopenharmony_ci{ 3758c2ecf20Sopenharmony_ci const unsigned long *p = vaddr; 3768c2ecf20Sopenharmony_ci int res = 32; 3778c2ecf20Sopenharmony_ci unsigned int words; 3788c2ecf20Sopenharmony_ci unsigned long num; 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci if (!size) 3818c2ecf20Sopenharmony_ci return 0; 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci words = (size + 31) >> 5; 3848c2ecf20Sopenharmony_ci while (!(num = *p++)) { 3858c2ecf20Sopenharmony_ci if (!--words) 3868c2ecf20Sopenharmony_ci goto out; 3878c2ecf20Sopenharmony_ci } 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 3908c2ecf20Sopenharmony_ci : "=d" (res) : "d" (num & -num)); 3918c2ecf20Sopenharmony_ci res ^= 31; 3928c2ecf20Sopenharmony_ciout: 3938c2ecf20Sopenharmony_ci res += ((long)p - (long)vaddr - 4) * 8; 3948c2ecf20Sopenharmony_ci return res < size ? res : size; 3958c2ecf20Sopenharmony_ci} 3968c2ecf20Sopenharmony_ci#define find_first_bit find_first_bit 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_cistatic inline int find_next_bit(const unsigned long *vaddr, int size, 3998c2ecf20Sopenharmony_ci int offset) 4008c2ecf20Sopenharmony_ci{ 4018c2ecf20Sopenharmony_ci const unsigned long *p = vaddr + (offset >> 5); 4028c2ecf20Sopenharmony_ci int bit = offset & 31UL, res; 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci if (offset >= size) 4058c2ecf20Sopenharmony_ci return size; 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_ci if (bit) { 4088c2ecf20Sopenharmony_ci unsigned long num = *p++ & (~0UL << bit); 4098c2ecf20Sopenharmony_ci offset -= bit; 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci /* Look for one in first longword */ 4128c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 4138c2ecf20Sopenharmony_ci : "=d" (res) : "d" (num & -num)); 4148c2ecf20Sopenharmony_ci if (res < 32) { 4158c2ecf20Sopenharmony_ci offset += res ^ 31; 4168c2ecf20Sopenharmony_ci return offset < size ? offset : size; 4178c2ecf20Sopenharmony_ci } 4188c2ecf20Sopenharmony_ci offset += 32; 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci if (offset >= size) 4218c2ecf20Sopenharmony_ci return size; 4228c2ecf20Sopenharmony_ci } 4238c2ecf20Sopenharmony_ci /* No one yet, search remaining full bytes for a one */ 4248c2ecf20Sopenharmony_ci return offset + find_first_bit(p, size - offset); 4258c2ecf20Sopenharmony_ci} 4268c2ecf20Sopenharmony_ci#define find_next_bit find_next_bit 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci/* 4298c2ecf20Sopenharmony_ci * ffz = Find First Zero in word. Undefined if no zero exists, 4308c2ecf20Sopenharmony_ci * so code should check against ~0UL first.. 4318c2ecf20Sopenharmony_ci */ 4328c2ecf20Sopenharmony_cistatic inline unsigned long ffz(unsigned long word) 4338c2ecf20Sopenharmony_ci{ 4348c2ecf20Sopenharmony_ci int res; 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bfffo %1{#0,#0},%0" 4378c2ecf20Sopenharmony_ci : "=d" (res) : "d" (~word & -~word)); 4388c2ecf20Sopenharmony_ci return res ^ 31; 4398c2ecf20Sopenharmony_ci} 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci#endif 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci#include <asm-generic/bitops/find.h> 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_ci#ifdef __KERNEL__ 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_HAS_NO_BITFIELDS) 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_ci/* 4508c2ecf20Sopenharmony_ci * The newer ColdFire family members support a "bitrev" instruction 4518c2ecf20Sopenharmony_ci * and we can use that to implement a fast ffs. Older Coldfire parts, 4528c2ecf20Sopenharmony_ci * and normal 68000 parts don't have anything special, so we use the 4538c2ecf20Sopenharmony_ci * generic functions for those. 4548c2ecf20Sopenharmony_ci */ 4558c2ecf20Sopenharmony_ci#if (defined(__mcfisaaplus__) || defined(__mcfisac__)) && \ 4568c2ecf20Sopenharmony_ci !defined(CONFIG_M68000) && !defined(CONFIG_MCPU32) 4578c2ecf20Sopenharmony_cistatic inline unsigned long __ffs(unsigned long x) 4588c2ecf20Sopenharmony_ci{ 4598c2ecf20Sopenharmony_ci __asm__ __volatile__ ("bitrev %0; ff1 %0" 4608c2ecf20Sopenharmony_ci : "=d" (x) 4618c2ecf20Sopenharmony_ci : "0" (x)); 4628c2ecf20Sopenharmony_ci return x; 4638c2ecf20Sopenharmony_ci} 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_cistatic inline int ffs(int x) 4668c2ecf20Sopenharmony_ci{ 4678c2ecf20Sopenharmony_ci if (!x) 4688c2ecf20Sopenharmony_ci return 0; 4698c2ecf20Sopenharmony_ci return __ffs(x) + 1; 4708c2ecf20Sopenharmony_ci} 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci#else 4738c2ecf20Sopenharmony_ci#include <asm-generic/bitops/ffs.h> 4748c2ecf20Sopenharmony_ci#include <asm-generic/bitops/__ffs.h> 4758c2ecf20Sopenharmony_ci#endif 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_ci#include <asm-generic/bitops/fls.h> 4788c2ecf20Sopenharmony_ci#include <asm-generic/bitops/__fls.h> 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_ci#else 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_ci/* 4838c2ecf20Sopenharmony_ci * ffs: find first bit set. This is defined the same way as 4848c2ecf20Sopenharmony_ci * the libc and compiler builtin ffs routines, therefore 4858c2ecf20Sopenharmony_ci * differs in spirit from the above ffz (man ffs). 4868c2ecf20Sopenharmony_ci */ 4878c2ecf20Sopenharmony_cistatic inline int ffs(int x) 4888c2ecf20Sopenharmony_ci{ 4898c2ecf20Sopenharmony_ci int cnt; 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_ci __asm__ ("bfffo %1{#0:#0},%0" 4928c2ecf20Sopenharmony_ci : "=d" (cnt) 4938c2ecf20Sopenharmony_ci : "dm" (x & -x)); 4948c2ecf20Sopenharmony_ci return 32 - cnt; 4958c2ecf20Sopenharmony_ci} 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_cistatic inline unsigned long __ffs(unsigned long x) 4988c2ecf20Sopenharmony_ci{ 4998c2ecf20Sopenharmony_ci return ffs(x) - 1; 5008c2ecf20Sopenharmony_ci} 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_ci/* 5038c2ecf20Sopenharmony_ci * fls: find last bit set. 5048c2ecf20Sopenharmony_ci */ 5058c2ecf20Sopenharmony_cistatic inline int fls(unsigned int x) 5068c2ecf20Sopenharmony_ci{ 5078c2ecf20Sopenharmony_ci int cnt; 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci __asm__ ("bfffo %1{#0,#0},%0" 5108c2ecf20Sopenharmony_ci : "=d" (cnt) 5118c2ecf20Sopenharmony_ci : "dm" (x)); 5128c2ecf20Sopenharmony_ci return 32 - cnt; 5138c2ecf20Sopenharmony_ci} 5148c2ecf20Sopenharmony_ci 5158c2ecf20Sopenharmony_cistatic inline int __fls(int x) 5168c2ecf20Sopenharmony_ci{ 5178c2ecf20Sopenharmony_ci return fls(x) - 1; 5188c2ecf20Sopenharmony_ci} 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_ci#endif 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_ci/* Simple test-and-set bit locks */ 5238c2ecf20Sopenharmony_ci#define test_and_set_bit_lock test_and_set_bit 5248c2ecf20Sopenharmony_ci#define clear_bit_unlock clear_bit 5258c2ecf20Sopenharmony_ci#define __clear_bit_unlock clear_bit_unlock 5268c2ecf20Sopenharmony_ci 5278c2ecf20Sopenharmony_ci#include <asm-generic/bitops/ext2-atomic.h> 5288c2ecf20Sopenharmony_ci#include <asm-generic/bitops/le.h> 5298c2ecf20Sopenharmony_ci#include <asm-generic/bitops/fls64.h> 5308c2ecf20Sopenharmony_ci#include <asm-generic/bitops/sched.h> 5318c2ecf20Sopenharmony_ci#include <asm-generic/bitops/hweight.h> 5328c2ecf20Sopenharmony_ci#endif /* __KERNEL__ */ 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_ci#endif /* _M68K_BITOPS_H */ 535