162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 362306a36Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 462306a36Sopenharmony_ci * for more details. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (c) 1994 - 1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org) 762306a36Sopenharmony_ci * Copyright (c) 1999, 2000 Silicon Graphics, Inc. 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci#ifndef _ASM_BITOPS_H 1062306a36Sopenharmony_ci#define _ASM_BITOPS_H 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#ifndef _LINUX_BITOPS_H 1362306a36Sopenharmony_ci#error only <linux/bitops.h> can be included directly 1462306a36Sopenharmony_ci#endif 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include <linux/bits.h> 1762306a36Sopenharmony_ci#include <linux/compiler.h> 1862306a36Sopenharmony_ci#include <linux/types.h> 1962306a36Sopenharmony_ci#include <asm/asm.h> 2062306a36Sopenharmony_ci#include <asm/barrier.h> 2162306a36Sopenharmony_ci#include <asm/byteorder.h> /* sigh ... */ 2262306a36Sopenharmony_ci#include <asm/compiler.h> 2362306a36Sopenharmony_ci#include <asm/cpu-features.h> 2462306a36Sopenharmony_ci#include <asm/sgidefs.h> 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#define __bit_op(mem, insn, inputs...) do { \ 2762306a36Sopenharmony_ci unsigned long __temp; \ 2862306a36Sopenharmony_ci \ 2962306a36Sopenharmony_ci asm volatile( \ 3062306a36Sopenharmony_ci " .set push \n" \ 3162306a36Sopenharmony_ci " .set " MIPS_ISA_LEVEL " \n" \ 3262306a36Sopenharmony_ci " " __SYNC(full, loongson3_war) " \n" \ 3362306a36Sopenharmony_ci "1: " __stringify(LONG_LL) " %0, %1 \n" \ 3462306a36Sopenharmony_ci " " insn " \n" \ 3562306a36Sopenharmony_ci " " __stringify(LONG_SC) " %0, %1 \n" \ 3662306a36Sopenharmony_ci " " __stringify(SC_BEQZ) " %0, 1b \n" \ 3762306a36Sopenharmony_ci " .set pop \n" \ 3862306a36Sopenharmony_ci : "=&r"(__temp), "+" GCC_OFF_SMALL_ASM()(mem) \ 3962306a36Sopenharmony_ci : inputs \ 4062306a36Sopenharmony_ci : __LLSC_CLOBBER); \ 4162306a36Sopenharmony_ci} while (0) 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#define __test_bit_op(mem, ll_dst, insn, inputs...) ({ \ 4462306a36Sopenharmony_ci unsigned long __orig, __temp; \ 4562306a36Sopenharmony_ci \ 4662306a36Sopenharmony_ci asm volatile( \ 4762306a36Sopenharmony_ci " .set push \n" \ 4862306a36Sopenharmony_ci " .set " MIPS_ISA_LEVEL " \n" \ 4962306a36Sopenharmony_ci " " __SYNC(full, loongson3_war) " \n" \ 5062306a36Sopenharmony_ci "1: " __stringify(LONG_LL) " " ll_dst ", %2\n" \ 5162306a36Sopenharmony_ci " " insn " \n" \ 5262306a36Sopenharmony_ci " " __stringify(LONG_SC) " %1, %2 \n" \ 5362306a36Sopenharmony_ci " " __stringify(SC_BEQZ) " %1, 1b \n" \ 5462306a36Sopenharmony_ci " .set pop \n" \ 5562306a36Sopenharmony_ci : "=&r"(__orig), "=&r"(__temp), \ 5662306a36Sopenharmony_ci "+" GCC_OFF_SMALL_ASM()(mem) \ 5762306a36Sopenharmony_ci : inputs \ 5862306a36Sopenharmony_ci : __LLSC_CLOBBER); \ 5962306a36Sopenharmony_ci \ 6062306a36Sopenharmony_ci __orig; \ 6162306a36Sopenharmony_ci}) 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci/* 6462306a36Sopenharmony_ci * These are the "slower" versions of the functions and are in bitops.c. 6562306a36Sopenharmony_ci * These functions call raw_local_irq_{save,restore}(). 6662306a36Sopenharmony_ci */ 6762306a36Sopenharmony_civoid __mips_set_bit(unsigned long nr, volatile unsigned long *addr); 6862306a36Sopenharmony_civoid __mips_clear_bit(unsigned long nr, volatile unsigned long *addr); 6962306a36Sopenharmony_civoid __mips_change_bit(unsigned long nr, volatile unsigned long *addr); 7062306a36Sopenharmony_ciint __mips_test_and_set_bit_lock(unsigned long nr, 7162306a36Sopenharmony_ci volatile unsigned long *addr); 7262306a36Sopenharmony_ciint __mips_test_and_clear_bit(unsigned long nr, 7362306a36Sopenharmony_ci volatile unsigned long *addr); 7462306a36Sopenharmony_ciint __mips_test_and_change_bit(unsigned long nr, 7562306a36Sopenharmony_ci volatile unsigned long *addr); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci/* 7962306a36Sopenharmony_ci * set_bit - Atomically set a bit in memory 8062306a36Sopenharmony_ci * @nr: the bit to set 8162306a36Sopenharmony_ci * @addr: the address to start counting from 8262306a36Sopenharmony_ci * 8362306a36Sopenharmony_ci * This function is atomic and may not be reordered. See __set_bit() 8462306a36Sopenharmony_ci * if you do not require the atomic guarantees. 8562306a36Sopenharmony_ci * Note that @nr may be almost arbitrarily large; this function is not 8662306a36Sopenharmony_ci * restricted to acting on a single-word quantity. 8762306a36Sopenharmony_ci */ 8862306a36Sopenharmony_cistatic inline void set_bit(unsigned long nr, volatile unsigned long *addr) 8962306a36Sopenharmony_ci{ 9062306a36Sopenharmony_ci volatile unsigned long *m = &addr[BIT_WORD(nr)]; 9162306a36Sopenharmony_ci int bit = nr % BITS_PER_LONG; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci if (!kernel_uses_llsc) { 9462306a36Sopenharmony_ci __mips_set_bit(nr, addr); 9562306a36Sopenharmony_ci return; 9662306a36Sopenharmony_ci } 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci if ((MIPS_ISA_REV >= 2) && __builtin_constant_p(bit) && (bit >= 16)) { 9962306a36Sopenharmony_ci __bit_op(*m, __stringify(LONG_INS) " %0, %3, %2, 1", "i"(bit), "r"(~0)); 10062306a36Sopenharmony_ci return; 10162306a36Sopenharmony_ci } 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci __bit_op(*m, "or\t%0, %2", "ir"(BIT(bit))); 10462306a36Sopenharmony_ci} 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci/* 10762306a36Sopenharmony_ci * clear_bit - Clears a bit in memory 10862306a36Sopenharmony_ci * @nr: Bit to clear 10962306a36Sopenharmony_ci * @addr: Address to start counting from 11062306a36Sopenharmony_ci * 11162306a36Sopenharmony_ci * clear_bit() is atomic and may not be reordered. However, it does 11262306a36Sopenharmony_ci * not contain a memory barrier, so if it is used for locking purposes, 11362306a36Sopenharmony_ci * you should call smp_mb__before_atomic() and/or smp_mb__after_atomic() 11462306a36Sopenharmony_ci * in order to ensure changes are visible on other processors. 11562306a36Sopenharmony_ci */ 11662306a36Sopenharmony_cistatic inline void clear_bit(unsigned long nr, volatile unsigned long *addr) 11762306a36Sopenharmony_ci{ 11862306a36Sopenharmony_ci volatile unsigned long *m = &addr[BIT_WORD(nr)]; 11962306a36Sopenharmony_ci int bit = nr % BITS_PER_LONG; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci if (!kernel_uses_llsc) { 12262306a36Sopenharmony_ci __mips_clear_bit(nr, addr); 12362306a36Sopenharmony_ci return; 12462306a36Sopenharmony_ci } 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci if ((MIPS_ISA_REV >= 2) && __builtin_constant_p(bit)) { 12762306a36Sopenharmony_ci __bit_op(*m, __stringify(LONG_INS) " %0, $0, %2, 1", "i"(bit)); 12862306a36Sopenharmony_ci return; 12962306a36Sopenharmony_ci } 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci __bit_op(*m, "and\t%0, %2", "ir"(~BIT(bit))); 13262306a36Sopenharmony_ci} 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci/* 13562306a36Sopenharmony_ci * clear_bit_unlock - Clears a bit in memory 13662306a36Sopenharmony_ci * @nr: Bit to clear 13762306a36Sopenharmony_ci * @addr: Address to start counting from 13862306a36Sopenharmony_ci * 13962306a36Sopenharmony_ci * clear_bit() is atomic and implies release semantics before the memory 14062306a36Sopenharmony_ci * operation. It can be used for an unlock. 14162306a36Sopenharmony_ci */ 14262306a36Sopenharmony_cistatic inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) 14362306a36Sopenharmony_ci{ 14462306a36Sopenharmony_ci smp_mb__before_atomic(); 14562306a36Sopenharmony_ci clear_bit(nr, addr); 14662306a36Sopenharmony_ci} 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci/* 14962306a36Sopenharmony_ci * change_bit - Toggle a bit in memory 15062306a36Sopenharmony_ci * @nr: Bit to change 15162306a36Sopenharmony_ci * @addr: Address to start counting from 15262306a36Sopenharmony_ci * 15362306a36Sopenharmony_ci * change_bit() is atomic and may not be reordered. 15462306a36Sopenharmony_ci * Note that @nr may be almost arbitrarily large; this function is not 15562306a36Sopenharmony_ci * restricted to acting on a single-word quantity. 15662306a36Sopenharmony_ci */ 15762306a36Sopenharmony_cistatic inline void change_bit(unsigned long nr, volatile unsigned long *addr) 15862306a36Sopenharmony_ci{ 15962306a36Sopenharmony_ci volatile unsigned long *m = &addr[BIT_WORD(nr)]; 16062306a36Sopenharmony_ci int bit = nr % BITS_PER_LONG; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci if (!kernel_uses_llsc) { 16362306a36Sopenharmony_ci __mips_change_bit(nr, addr); 16462306a36Sopenharmony_ci return; 16562306a36Sopenharmony_ci } 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci __bit_op(*m, "xor\t%0, %2", "ir"(BIT(bit))); 16862306a36Sopenharmony_ci} 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci/* 17162306a36Sopenharmony_ci * test_and_set_bit_lock - Set a bit and return its old value 17262306a36Sopenharmony_ci * @nr: Bit to set 17362306a36Sopenharmony_ci * @addr: Address to count from 17462306a36Sopenharmony_ci * 17562306a36Sopenharmony_ci * This operation is atomic and implies acquire ordering semantics 17662306a36Sopenharmony_ci * after the memory operation. 17762306a36Sopenharmony_ci */ 17862306a36Sopenharmony_cistatic inline int test_and_set_bit_lock(unsigned long nr, 17962306a36Sopenharmony_ci volatile unsigned long *addr) 18062306a36Sopenharmony_ci{ 18162306a36Sopenharmony_ci volatile unsigned long *m = &addr[BIT_WORD(nr)]; 18262306a36Sopenharmony_ci int bit = nr % BITS_PER_LONG; 18362306a36Sopenharmony_ci unsigned long res, orig; 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci if (!kernel_uses_llsc) { 18662306a36Sopenharmony_ci res = __mips_test_and_set_bit_lock(nr, addr); 18762306a36Sopenharmony_ci } else { 18862306a36Sopenharmony_ci orig = __test_bit_op(*m, "%0", 18962306a36Sopenharmony_ci "or\t%1, %0, %3", 19062306a36Sopenharmony_ci "ir"(BIT(bit))); 19162306a36Sopenharmony_ci res = (orig & BIT(bit)) != 0; 19262306a36Sopenharmony_ci } 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci smp_llsc_mb(); 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci return res; 19762306a36Sopenharmony_ci} 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci/* 20062306a36Sopenharmony_ci * test_and_set_bit - Set a bit and return its old value 20162306a36Sopenharmony_ci * @nr: Bit to set 20262306a36Sopenharmony_ci * @addr: Address to count from 20362306a36Sopenharmony_ci * 20462306a36Sopenharmony_ci * This operation is atomic and cannot be reordered. 20562306a36Sopenharmony_ci * It also implies a memory barrier. 20662306a36Sopenharmony_ci */ 20762306a36Sopenharmony_cistatic inline int test_and_set_bit(unsigned long nr, 20862306a36Sopenharmony_ci volatile unsigned long *addr) 20962306a36Sopenharmony_ci{ 21062306a36Sopenharmony_ci smp_mb__before_atomic(); 21162306a36Sopenharmony_ci return test_and_set_bit_lock(nr, addr); 21262306a36Sopenharmony_ci} 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci/* 21562306a36Sopenharmony_ci * test_and_clear_bit - Clear a bit and return its old value 21662306a36Sopenharmony_ci * @nr: Bit to clear 21762306a36Sopenharmony_ci * @addr: Address to count from 21862306a36Sopenharmony_ci * 21962306a36Sopenharmony_ci * This operation is atomic and cannot be reordered. 22062306a36Sopenharmony_ci * It also implies a memory barrier. 22162306a36Sopenharmony_ci */ 22262306a36Sopenharmony_cistatic inline int test_and_clear_bit(unsigned long nr, 22362306a36Sopenharmony_ci volatile unsigned long *addr) 22462306a36Sopenharmony_ci{ 22562306a36Sopenharmony_ci volatile unsigned long *m = &addr[BIT_WORD(nr)]; 22662306a36Sopenharmony_ci int bit = nr % BITS_PER_LONG; 22762306a36Sopenharmony_ci unsigned long res, orig; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci smp_mb__before_atomic(); 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci if (!kernel_uses_llsc) { 23262306a36Sopenharmony_ci res = __mips_test_and_clear_bit(nr, addr); 23362306a36Sopenharmony_ci } else if ((MIPS_ISA_REV >= 2) && __builtin_constant_p(nr)) { 23462306a36Sopenharmony_ci res = __test_bit_op(*m, "%1", 23562306a36Sopenharmony_ci __stringify(LONG_EXT) " %0, %1, %3, 1;" 23662306a36Sopenharmony_ci __stringify(LONG_INS) " %1, $0, %3, 1", 23762306a36Sopenharmony_ci "i"(bit)); 23862306a36Sopenharmony_ci } else { 23962306a36Sopenharmony_ci orig = __test_bit_op(*m, "%0", 24062306a36Sopenharmony_ci "or\t%1, %0, %3;" 24162306a36Sopenharmony_ci "xor\t%1, %1, %3", 24262306a36Sopenharmony_ci "ir"(BIT(bit))); 24362306a36Sopenharmony_ci res = (orig & BIT(bit)) != 0; 24462306a36Sopenharmony_ci } 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci smp_llsc_mb(); 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci return res; 24962306a36Sopenharmony_ci} 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci/* 25262306a36Sopenharmony_ci * test_and_change_bit - Change a bit and return its old value 25362306a36Sopenharmony_ci * @nr: Bit to change 25462306a36Sopenharmony_ci * @addr: Address to count from 25562306a36Sopenharmony_ci * 25662306a36Sopenharmony_ci * This operation is atomic and cannot be reordered. 25762306a36Sopenharmony_ci * It also implies a memory barrier. 25862306a36Sopenharmony_ci */ 25962306a36Sopenharmony_cistatic inline int test_and_change_bit(unsigned long nr, 26062306a36Sopenharmony_ci volatile unsigned long *addr) 26162306a36Sopenharmony_ci{ 26262306a36Sopenharmony_ci volatile unsigned long *m = &addr[BIT_WORD(nr)]; 26362306a36Sopenharmony_ci int bit = nr % BITS_PER_LONG; 26462306a36Sopenharmony_ci unsigned long res, orig; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci smp_mb__before_atomic(); 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci if (!kernel_uses_llsc) { 26962306a36Sopenharmony_ci res = __mips_test_and_change_bit(nr, addr); 27062306a36Sopenharmony_ci } else { 27162306a36Sopenharmony_ci orig = __test_bit_op(*m, "%0", 27262306a36Sopenharmony_ci "xor\t%1, %0, %3", 27362306a36Sopenharmony_ci "ir"(BIT(bit))); 27462306a36Sopenharmony_ci res = (orig & BIT(bit)) != 0; 27562306a36Sopenharmony_ci } 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci smp_llsc_mb(); 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci return res; 28062306a36Sopenharmony_ci} 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci#undef __bit_op 28362306a36Sopenharmony_ci#undef __test_bit_op 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci#include <asm-generic/bitops/non-atomic.h> 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci/* 28862306a36Sopenharmony_ci * __clear_bit_unlock - Clears a bit in memory 28962306a36Sopenharmony_ci * @nr: Bit to clear 29062306a36Sopenharmony_ci * @addr: Address to start counting from 29162306a36Sopenharmony_ci * 29262306a36Sopenharmony_ci * __clear_bit() is non-atomic and implies release semantics before the memory 29362306a36Sopenharmony_ci * operation. It can be used for an unlock if no other CPUs can concurrently 29462306a36Sopenharmony_ci * modify other bits in the word. 29562306a36Sopenharmony_ci */ 29662306a36Sopenharmony_cistatic inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) 29762306a36Sopenharmony_ci{ 29862306a36Sopenharmony_ci smp_mb__before_llsc(); 29962306a36Sopenharmony_ci __clear_bit(nr, addr); 30062306a36Sopenharmony_ci nudge_writes(); 30162306a36Sopenharmony_ci} 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci/* 30462306a36Sopenharmony_ci * Return the bit position (0..63) of the most significant 1 bit in a word 30562306a36Sopenharmony_ci * Returns -1 if no 1 bit exists 30662306a36Sopenharmony_ci */ 30762306a36Sopenharmony_cistatic __always_inline unsigned long __fls(unsigned long word) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci int num; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci if (BITS_PER_LONG == 32 && !__builtin_constant_p(word) && 31262306a36Sopenharmony_ci __builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) { 31362306a36Sopenharmony_ci __asm__( 31462306a36Sopenharmony_ci " .set push \n" 31562306a36Sopenharmony_ci " .set "MIPS_ISA_LEVEL" \n" 31662306a36Sopenharmony_ci " clz %0, %1 \n" 31762306a36Sopenharmony_ci " .set pop \n" 31862306a36Sopenharmony_ci : "=r" (num) 31962306a36Sopenharmony_ci : "r" (word)); 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci return 31 - num; 32262306a36Sopenharmony_ci } 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci if (BITS_PER_LONG == 64 && !__builtin_constant_p(word) && 32562306a36Sopenharmony_ci __builtin_constant_p(cpu_has_mips64) && cpu_has_mips64) { 32662306a36Sopenharmony_ci __asm__( 32762306a36Sopenharmony_ci " .set push \n" 32862306a36Sopenharmony_ci " .set "MIPS_ISA_LEVEL" \n" 32962306a36Sopenharmony_ci " dclz %0, %1 \n" 33062306a36Sopenharmony_ci " .set pop \n" 33162306a36Sopenharmony_ci : "=r" (num) 33262306a36Sopenharmony_ci : "r" (word)); 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci return 63 - num; 33562306a36Sopenharmony_ci } 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci num = BITS_PER_LONG - 1; 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci#if BITS_PER_LONG == 64 34062306a36Sopenharmony_ci if (!(word & (~0ul << 32))) { 34162306a36Sopenharmony_ci num -= 32; 34262306a36Sopenharmony_ci word <<= 32; 34362306a36Sopenharmony_ci } 34462306a36Sopenharmony_ci#endif 34562306a36Sopenharmony_ci if (!(word & (~0ul << (BITS_PER_LONG-16)))) { 34662306a36Sopenharmony_ci num -= 16; 34762306a36Sopenharmony_ci word <<= 16; 34862306a36Sopenharmony_ci } 34962306a36Sopenharmony_ci if (!(word & (~0ul << (BITS_PER_LONG-8)))) { 35062306a36Sopenharmony_ci num -= 8; 35162306a36Sopenharmony_ci word <<= 8; 35262306a36Sopenharmony_ci } 35362306a36Sopenharmony_ci if (!(word & (~0ul << (BITS_PER_LONG-4)))) { 35462306a36Sopenharmony_ci num -= 4; 35562306a36Sopenharmony_ci word <<= 4; 35662306a36Sopenharmony_ci } 35762306a36Sopenharmony_ci if (!(word & (~0ul << (BITS_PER_LONG-2)))) { 35862306a36Sopenharmony_ci num -= 2; 35962306a36Sopenharmony_ci word <<= 2; 36062306a36Sopenharmony_ci } 36162306a36Sopenharmony_ci if (!(word & (~0ul << (BITS_PER_LONG-1)))) 36262306a36Sopenharmony_ci num -= 1; 36362306a36Sopenharmony_ci return num; 36462306a36Sopenharmony_ci} 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci/* 36762306a36Sopenharmony_ci * __ffs - find first bit in word. 36862306a36Sopenharmony_ci * @word: The word to search 36962306a36Sopenharmony_ci * 37062306a36Sopenharmony_ci * Returns 0..SZLONG-1 37162306a36Sopenharmony_ci * Undefined if no bit exists, so code should check against 0 first. 37262306a36Sopenharmony_ci */ 37362306a36Sopenharmony_cistatic __always_inline unsigned long __ffs(unsigned long word) 37462306a36Sopenharmony_ci{ 37562306a36Sopenharmony_ci return __fls(word & -word); 37662306a36Sopenharmony_ci} 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci/* 37962306a36Sopenharmony_ci * fls - find last bit set. 38062306a36Sopenharmony_ci * @word: The word to search 38162306a36Sopenharmony_ci * 38262306a36Sopenharmony_ci * This is defined the same way as ffs. 38362306a36Sopenharmony_ci * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. 38462306a36Sopenharmony_ci */ 38562306a36Sopenharmony_cistatic inline int fls(unsigned int x) 38662306a36Sopenharmony_ci{ 38762306a36Sopenharmony_ci int r; 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci if (!__builtin_constant_p(x) && 39062306a36Sopenharmony_ci __builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) { 39162306a36Sopenharmony_ci __asm__( 39262306a36Sopenharmony_ci " .set push \n" 39362306a36Sopenharmony_ci " .set "MIPS_ISA_LEVEL" \n" 39462306a36Sopenharmony_ci " clz %0, %1 \n" 39562306a36Sopenharmony_ci " .set pop \n" 39662306a36Sopenharmony_ci : "=r" (x) 39762306a36Sopenharmony_ci : "r" (x)); 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci return 32 - x; 40062306a36Sopenharmony_ci } 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci r = 32; 40362306a36Sopenharmony_ci if (!x) 40462306a36Sopenharmony_ci return 0; 40562306a36Sopenharmony_ci if (!(x & 0xffff0000u)) { 40662306a36Sopenharmony_ci x <<= 16; 40762306a36Sopenharmony_ci r -= 16; 40862306a36Sopenharmony_ci } 40962306a36Sopenharmony_ci if (!(x & 0xff000000u)) { 41062306a36Sopenharmony_ci x <<= 8; 41162306a36Sopenharmony_ci r -= 8; 41262306a36Sopenharmony_ci } 41362306a36Sopenharmony_ci if (!(x & 0xf0000000u)) { 41462306a36Sopenharmony_ci x <<= 4; 41562306a36Sopenharmony_ci r -= 4; 41662306a36Sopenharmony_ci } 41762306a36Sopenharmony_ci if (!(x & 0xc0000000u)) { 41862306a36Sopenharmony_ci x <<= 2; 41962306a36Sopenharmony_ci r -= 2; 42062306a36Sopenharmony_ci } 42162306a36Sopenharmony_ci if (!(x & 0x80000000u)) { 42262306a36Sopenharmony_ci x <<= 1; 42362306a36Sopenharmony_ci r -= 1; 42462306a36Sopenharmony_ci } 42562306a36Sopenharmony_ci return r; 42662306a36Sopenharmony_ci} 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci#include <asm-generic/bitops/fls64.h> 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci/* 43162306a36Sopenharmony_ci * ffs - find first bit set. 43262306a36Sopenharmony_ci * @word: The word to search 43362306a36Sopenharmony_ci * 43462306a36Sopenharmony_ci * This is defined the same way as 43562306a36Sopenharmony_ci * the libc and compiler builtin ffs routines, therefore 43662306a36Sopenharmony_ci * differs in spirit from the below ffz (man ffs). 43762306a36Sopenharmony_ci */ 43862306a36Sopenharmony_cistatic inline int ffs(int word) 43962306a36Sopenharmony_ci{ 44062306a36Sopenharmony_ci if (!word) 44162306a36Sopenharmony_ci return 0; 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci return fls(word & -word); 44462306a36Sopenharmony_ci} 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci#include <asm-generic/bitops/ffz.h> 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci#ifdef __KERNEL__ 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci#include <asm-generic/bitops/sched.h> 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci#include <asm/arch_hweight.h> 45362306a36Sopenharmony_ci#include <asm-generic/bitops/const_hweight.h> 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci#include <asm-generic/bitops/le.h> 45662306a36Sopenharmony_ci#include <asm-generic/bitops/ext2-atomic.h> 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci#endif /* __KERNEL__ */ 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci#endif /* _ASM_BITOPS_H */ 461