config ARCH_NO_COHERENT_DMA_MMAP
        bool
 
+config CPU_NO_EFFICIENT_FFS
+       def_bool n
+
 source "kernel/gcov/Kconfig"
 
        select MODULES_USE_ELF_RELA
        select ODD_RT_SIGACTION
        select OLD_SIGSUSPEND
+       select CPU_NO_EFFICIENT_FFS if !ALPHA_EV67
        help
          The Alpha is a 64-bit general-purpose processor designed and
          marketed by the Digital Equipment Corporation of blessed memory,
 
 
 config ISA_ARCOMPACT
        bool "ARCompact ISA"
+       select CPU_NO_EFFICIENT_FFS
        help
          The original ARC ISA of ARC600/700 cores
 
 
        select CPU_USE_DOMAINS if MMU
        select NEED_KUSER_HELPERS
        select TLS_REG_EMUL if SMP || !MMU
+       select CPU_NO_EFFICIENT_FFS
 
 config CPU_32v4
        bool
        select CPU_USE_DOMAINS if MMU
        select NEED_KUSER_HELPERS
        select TLS_REG_EMUL if SMP || !MMU
+       select CPU_NO_EFFICIENT_FFS
 
 config CPU_32v4T
        bool
        select CPU_USE_DOMAINS if MMU
        select NEED_KUSER_HELPERS
        select TLS_REG_EMUL if SMP || !MMU
+       select CPU_NO_EFFICIENT_FFS
 
 config CPU_32v5
        bool
 
        select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_LZO
        select HAVE_ARCH_KGDB
+       select CPU_NO_EFFICIENT_FFS
 
 config RWSEM_GENERIC_SPINLOCK
        def_bool y
 
        select ARCH_USES_GETTIMEOFFSET
        select MODULES_USE_ELF_RELA
        select HAVE_DEBUG_STACKOVERFLOW
+       select CPU_NO_EFFICIENT_FFS
 
 config SBUS
        bool
 
        select CPU_HAS_NO_MULDIV64
        select CPU_HAS_NO_UNALIGNED
        select GENERIC_CSUM
+       select CPU_NO_EFFICIENT_FFS
        help
          The Freescale (was Motorola) 68000 CPU is the first generation of
          the well known M68K family of processors. The CPU core as well as
        bool
        select CPU_HAS_NO_BITFIELDS
        select CPU_HAS_NO_UNALIGNED
+       select CPU_NO_EFFICIENT_FFS
        help
          The Freescale (was then Motorola) CPU32 is a CPU core that is
          based on the 68020 processor. For the most part it is used in
        depends on !MMU
        select COLDFIRE_SW_A7
        select HAVE_MBAR
+       select CPU_NO_EFFICIENT_FFS
        help
          Motorola ColdFire 5206 processor support.
 
        depends on !MMU
        select COLDFIRE_SW_A7
        select HAVE_MBAR
+       select CPU_NO_EFFICIENT_FFS
        help
          Motorola ColdFire 5206e processor support.
 
        depends on !MMU
        select COLDFIRE_SW_A7
        select HAVE_MBAR
+       select CPU_NO_EFFICIENT_FFS
        help
          Motorola ColdFire 5249 processor support.
 
        depends on !MMU
        select COLDFIRE_SW_A7
        select HAVE_MBAR
+       select CPU_NO_EFFICIENT_FFS
        help
          Freescale (Motorola) Coldfire 5251/5253 processor support.
 
        depends on !MMU
        select COLDFIRE_SW_A7
        select HAVE_MBAR
+       select CPU_NO_EFFICIENT_FFS
        help
          Motorola ColdFire 5272 processor support.
 
        select COLDFIRE_SW_A7
        select HAVE_CACHE_CB
        select HAVE_MBAR
+       select CPU_NO_EFFICIENT_FFS
        help
          Motorola ColdFire 5307 processor support.
 
        select COLDFIRE_SW_A7
        select HAVE_CACHE_CB
        select HAVE_MBAR
+       select CPU_NO_EFFICIENT_FFS
        help
          Motorola ColdFire 5407 processor support.
 
        select MMU_COLDFIRE if MMU
        select HAVE_CACHE_CB
        select HAVE_MBAR
+       select CPU_NO_EFFICIENT_FFS
        help
          Freescale ColdFire 5470/5471/5472/5473/5474/5475 processor support.
 
        select M54xx
        select HAVE_CACHE_CB
        select HAVE_MBAR
+       select CPU_NO_EFFICIENT_FFS
        help
          Freescale ColdFire 5480/5481/5482/5483/5484/5485 processor support.
 
 
        select OF
        select OF_EARLY_FLATTREE
        select SPARSE_IRQ
+       select CPU_NO_EFFICIENT_FFS
 
 config STACKTRACE_SUPPORT
        def_bool y
 
        select OF_EARLY_FLATTREE
        select TRACING_SUPPORT
        select VIRT_TO_BUS
+       select CPU_NO_EFFICIENT_FFS
 
 config SWAP
        def_bool n
 
 #endif
 #endif
 
+/* __builtin_constant_p(cpu_has_mips_r) && cpu_has_mips_r */
+#if !((defined(cpu_has_mips32r1) && cpu_has_mips32r1) || \
+         (defined(cpu_has_mips32r2) && cpu_has_mips32r2) || \
+         (defined(cpu_has_mips32r6) && cpu_has_mips32r6) || \
+         (defined(cpu_has_mips64r1) && cpu_has_mips64r1) || \
+         (defined(cpu_has_mips64r2) && cpu_has_mips64r2) || \
+         (defined(cpu_has_mips64r6) && cpu_has_mips64r6))
+#define CPU_NO_EFFICIENT_FFS 1
+#endif
+
 #ifndef cpu_has_mips_1
 # define cpu_has_mips_1                (!cpu_has_mips_r6)
 #endif
 
        select SOC_BUS
        select SPARSE_IRQ
        select USB_ARCH_HAS_HCD if USB_SUPPORT
+       select CPU_NO_EFFICIENT_FFS
 
 config GENERIC_CSUM
        def_bool y
 
        select MODULES_USE_ELF_RELA
        select HAVE_DEBUG_STACKOVERFLOW
        select OR1K_PIC
+       select CPU_NO_EFFICIENT_FFS if !OPENRISC_HAVE_INST_FF1
 
 config MMU
        def_bool y
 
        select HAVE_ARCH_AUDITSYSCALL
        select HAVE_ARCH_SECCOMP_FILTER
        select ARCH_NO_COHERENT_DMA_MMAP
+       select CPU_NO_EFFICIENT_FFS
 
        help
          The PA-RISC microprocessor is designed by Hewlett-Packard and used
 
        select HAVE_ARCH_AUDITSYSCALL
        select HAVE_ARCH_EARLY_PFN_TO_NID
        select HAVE_ARCH_JUMP_LABEL
+       select CPU_NO_EFFICIENT_FFS if !HAVE_MARCH_Z9_109_FEATURES
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_SOFT_DIRTY
        select HAVE_ARCH_TRACEHOOK
 
        select VIRT_TO_BUS
        select MODULES_USE_ELF_REL
        select CLONE_BACKWARDS
+       select CPU_NO_EFFICIENT_FFS
 
 choice
        prompt "System type"
 
        select PERF_USE_VMALLOC
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_KERNEL_GZIP
+       select CPU_NO_EFFICIENT_FFS
        select HAVE_KERNEL_BZIP2
        select HAVE_KERNEL_LZMA
        select HAVE_KERNEL_XZ
 
        select ODD_RT_SIGACTION
        select OLD_SIGSUSPEND
        select ARCH_HAS_SG_CHAIN
+       select CPU_NO_EFFICIENT_FFS
 
 config SPARC32
        def_bool !64BIT
 
 #include <linux/gcd.h>
 #include <linux/export.h>
 
-/* Greatest common divisor */
+/*
+ * This implements the binary GCD algorithm. (Often attributed to Stein,
+ * but as Knuth has noted, appears in a first-century Chinese math text.)
+ *
+ * This is faster than the division-based algorithm even on x86, which
+ * has decent hardware division.
+ */
+
+#if !defined(CONFIG_CPU_NO_EFFICIENT_FFS) && !defined(CPU_NO_EFFICIENT_FFS)
+
+/* If __ffs is available, the even/odd algorithm benchmarks slower. */
 unsigned long gcd(unsigned long a, unsigned long b)
 {
-       unsigned long r;
+       unsigned long r = a | b;
+
+       if (!a || !b)
+               return r;
 
-       if (a < b)
-               swap(a, b);
+       b >>= __ffs(b);
+       if (b == 1)
+               return r & -r;
 
-       if (!b)
-               return a;
-       while ((r = a % b) != 0) {
-               a = b;
-               b = r;
+       for (;;) {
+               a >>= __ffs(a);
+               if (a == 1)
+                       return r & -r;
+               if (a == b)
+                       return a << __ffs(r);
+
+               if (a < b)
+                       swap(a, b);
+               a -= b;
        }
-       return b;
 }
+
+#else
+
+/* If normalization is done by loops, the even/odd algorithm is a win. */
+unsigned long gcd(unsigned long a, unsigned long b)
+{
+       unsigned long r = a | b;
+
+       if (!a || !b)
+               return r;
+
+       /* Isolate lsbit of r */
+       r &= -r;
+
+       while (!(b & r))
+               b >>= 1;
+       if (b == r)
+               return r;
+
+       for (;;) {
+               while (!(a & r))
+                       a >>= 1;
+               if (a == r)
+                       return r;
+               if (a == b)
+                       return a;
+
+               if (a < b)
+                       swap(a, b);
+               a -= b;
+               a >>= 1;
+               if (a & r)
+                       a += b;
+               a >>= 1;
+       }
+}
+
+#endif
+
 EXPORT_SYMBOL_GPL(gcd);