diff --git a/lib/Makefile b/lib/Makefile index e5cf32c..878c2fb 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -63,3 +63,4 @@ obj-y += list_sort.o obj-y += int_sqrt.o obj-y += parseopt.o +obj-y += clz_ctz.o diff --git a/lib/clz_ctz.c b/lib/clz_ctz.c new file mode 100644 index 0000000..b5ac7f4 --- /dev/null +++ b/lib/clz_ctz.c @@ -0,0 +1,59 @@ +/* + * lib/clz_ctz.c + * + * Copyright (C) 2013 Chanho Min + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * The functions in this file aren't called directly, but are required by + * GCC builtins such as __builtin_ctz, and therefore they can't be removed + * despite appearing unreferenced in kernel source. + * + * __c[lt]z[sd]i2 can be overridden by linking arch-specific versions. + */ + +#include +#include + +int __weak __ctzsi2(int val); +int __weak __ctzsi2(int val) +{ + return __ffs(val); +} + +int __weak __clzsi2(int val); +int __weak __clzsi2(int val) +{ + return 32 - fls(val); +} + +int __weak __clzdi2(long val); +int __weak __ctzdi2(long val); +#if BITS_PER_LONG == 32 + +int __weak __clzdi2(long val) +{ + return 32 - fls((int)val); +} + +int __weak __ctzdi2(long val) +{ + return __ffs((u32)val); +} + +#elif BITS_PER_LONG == 64 + +int __weak __clzdi2(long val) +{ + return 64 - fls64((u64)val); +} + +int __weak __ctzdi2(long val) +{ + return __ffs64((u64)val); +} + +#else +#error BITS_PER_LONG not 32 or 64 +#endif