Unify the CPU features vectors between i386 and x86-64

Unify the handling of the CPU features vectors between i386 and x86-64.
This also adopts the collapsing of features which are required at
compile-time into constant tests from x86-64 to i386.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
index f514e90..7ea5f4a 100644
--- a/include/asm-i386/cpufeature.h
+++ b/include/asm-i386/cpufeature.h
@@ -81,6 +81,7 @@
 #define X86_FEATURE_BTS		(3*32+13)  /* Branch Trace Store */
 #define X86_FEATURE_LAPIC_TIMER_BROKEN (3*32+ 14) /* lapic timer broken in C1 */
 #define X86_FEATURE_SYNC_RDTSC	(3*32+15)  /* RDTSC synchronizes the CPU */
+#define X86_FEATURE_REP_GOOD   (3*32+16) /* rep microcode works well on this CPU */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3	(4*32+ 0) /* Streaming SIMD Extensions-3 */
@@ -108,11 +109,17 @@
 #define X86_FEATURE_LAHF_LM	(6*32+ 0) /* LAHF/SAHF in long mode */
 #define X86_FEATURE_CMP_LEGACY	(6*32+ 1) /* If yes HyperThreading not valid */
 
-#define cpu_has(c, bit)					\
-	((__builtin_constant_p(bit) && (bit) < 32 && 	\
-		(1UL << (bit)) & REQUIRED_MASK1) ?	\
-		1 : 					\
-	test_bit(bit, (c)->x86_capability))
+#define cpu_has(c, bit)							\
+	(__builtin_constant_p(bit) &&					\
+	 ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) ||	\
+	   (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) ||	\
+	   (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) ||	\
+	   (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) ||	\
+	   (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) ||	\
+	   (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) ||	\
+	   (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) )	\
+	  ? 1 :								\
+	  test_bit(bit, (c)->x86_capability))
 #define boot_cpu_has(bit)	cpu_has(&boot_cpu_data, bit)
 
 #define cpu_has_fpu		boot_cpu_has(X86_FEATURE_FPU)
diff --git a/include/asm-i386/required-features.h b/include/asm-i386/required-features.h
index 9db866c..a9c3b11 100644
--- a/include/asm-i386/required-features.h
+++ b/include/asm-i386/required-features.h
@@ -3,32 +3,52 @@
 
 /* Define minimum CPUID feature set for kernel These bits are checked
    really early to actually display a visible error message before the
-   kernel dies.  Only add word 0 bits here
+   kernel dies.  Make sure to assign features to the proper mask!
 
    Some requirements that are not in CPUID yet are also in the
-   CONFIG_X86_MINIMUM_CPU mode which is checked too.
+   CONFIG_X86_MINIMUM_CPU_FAMILY which is checked too.
 
    The real information is in arch/i386/Kconfig.cpu, this just converts
    the CONFIGs into a bitmask */
 
-#ifdef CONFIG_X86_PAE
-#define NEED_PAE	(1<<X86_FEATURE_PAE)
+#ifndef CONFIG_MATH_EMULATION
+# define NEED_FPU	(1<<(X86_FEATURE_FPU & 31))
 #else
-#define NEED_PAE	0
+# define NEED_FPU	0
+#endif
+
+#ifdef CONFIG_X86_PAE
+# define NEED_PAE	(1<<(X86_FEATURE_PAE & 31))
+#else
+# define NEED_PAE	0
 #endif
 
 #ifdef CONFIG_X86_CMOV
-#define NEED_CMOV	(1<<X86_FEATURE_CMOV)
+# define NEED_CMOV	(1<<(X86_FEATURE_CMOV & 31))
 #else
-#define NEED_CMOV	0
+# define NEED_CMOV	0
 #endif
 
 #ifdef CONFIG_X86_CMPXCHG64
-#define NEED_CMPXCHG64  (1<<X86_FEATURE_CX8)
+# define NEED_CX8	(1<<(X86_FEATURE_CX8 & 31))
 #else
-#define NEED_CMPXCHG64  0
+# define NEED_CX8	0
 #endif
 
-#define REQUIRED_MASK1	(NEED_PAE|NEED_CMOV|NEED_CMPXCHG64)
+#define REQUIRED_MASK0	(NEED_FPU|NEED_PAE|NEED_CMOV|NEED_CX8)
+
+#ifdef CONFIG_X86_USE_3DNOW
+# define NEED_3DNOW	(1<<(X86_FEATURE_3DNOW & 31))
+#else
+# define NEED_3DNOW	0
+#endif
+
+#define REQUIRED_MASK1	(NEED_3DNOW)
+
+#define REQUIRED_MASK2	0
+#define REQUIRED_MASK3	0
+#define REQUIRED_MASK4	0
+#define REQUIRED_MASK5	0
+#define REQUIRED_MASK6	0
 
 #endif