0001
0002 #include <linux/kernel.h>
0003 #include <linux/gcd.h>
0004 #include <linux/export.h>
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #if !defined(CONFIG_CPU_NO_EFFICIENT_FFS)
0015
0016
0017
0018
0019
0020
0021
0022
0023 unsigned long gcd(unsigned long a, unsigned long b)
0024 {
0025 unsigned long r = a | b;
0026
0027 if (!a || !b)
0028 return r;
0029
0030 b >>= __ffs(b);
0031 if (b == 1)
0032 return r & -r;
0033
0034 for (;;) {
0035 a >>= __ffs(a);
0036 if (a == 1)
0037 return r & -r;
0038 if (a == b)
0039 return a << __ffs(r);
0040
0041 if (a < b)
0042 swap(a, b);
0043 a -= b;
0044 }
0045 }
0046
0047 #else
0048
0049
0050 unsigned long gcd(unsigned long a, unsigned long b)
0051 {
0052 unsigned long r = a | b;
0053
0054 if (!a || !b)
0055 return r;
0056
0057
0058 r &= -r;
0059
0060 while (!(b & r))
0061 b >>= 1;
0062 if (b == r)
0063 return r;
0064
0065 for (;;) {
0066 while (!(a & r))
0067 a >>= 1;
0068 if (a == r)
0069 return r;
0070 if (a == b)
0071 return a;
0072
0073 if (a < b)
0074 swap(a, b);
0075 a -= b;
0076 a >>= 1;
0077 if (a & r)
0078 a += b;
0079 a >>= 1;
0080 }
0081 }
0082
0083 #endif
0084
0085 EXPORT_SYMBOL_GPL(gcd);