MIPS: Hardcode cpu_has_mips* where target ISA allows
authorPaul Burton <paul.burton@mips.com>
Mon, 26 Nov 2018 18:58:40 +0000 (18:58 +0000)
committerPaul Burton <paul.burton@mips.com>
Tue, 27 Nov 2018 06:49:20 +0000 (22:49 -0800)
In the same vein as commit 93e01942a6eb ("MIPS: Hardcode cpu_has_* where
known at compile time due to ISA"), we can use our knowledge of the ISA
being targeted by the kernel build to make cpu_has_mips* macros
compile-time constant in some cases. This allows the compiler greater
opportunity to optimize out code which will never execute.

Signed-off-by: Paul Burton <paul.burton@mips.com>
Patchwork: https://patchwork.linux-mips.org/patch/21245/
Cc: linux-mips@linux-mips.org
arch/mips/include/asm/cpu-features.h

index ca348356f76fbfdd8725f6fa8b70a6666ad85fba..701e525641b86293a51d9e667783c15f15374685 100644 (file)
@@ -15,6 +15,7 @@
 #include <cpu-feature-overrides.h>
 
 #define __ase(ase)                     (cpu_data[0].ases & (ase))
+#define __isa(isa)                     (cpu_data[0].isa_level & (isa))
 #define __opt(opt)                     (cpu_data[0].options & (opt))
 
 /*
 #define __isa_lt_and_ase(isa, ase)     ((MIPS_ISA_REV < (isa)) && __ase(ase))
 #define __isa_lt_and_opt(isa, opt)     ((MIPS_ISA_REV < (isa)) && __opt(opt))
 
+/*
+ * Similarly allow for ISA level checks that take into account knowledge of the
+ * ISA targeted by the kernel build, provided by MIPS_ISA_REV.
+ */
+#define __isa_ge_and_flag(isa, flag)   ((MIPS_ISA_REV >= (isa)) && __isa(flag))
+#define __isa_ge_or_flag(isa, flag)    ((MIPS_ISA_REV >= (isa)) || __isa(flag))
+#define __isa_lt_and_flag(isa, flag)   ((MIPS_ISA_REV < (isa)) && __isa(flag))
+#define __isa_range(ge, lt) \
+       ((MIPS_ISA_REV >= (ge)) && (MIPS_ISA_REV < (lt)))
+#define __isa_range_or_flag(ge, lt, flag) \
+       (__isa_range(ge, lt) || ((MIPS_ISA_REV < (lt)) && __isa(flag)))
+
 /*
  * SMP assumption: Options of CPU 0 are a superset of all processors.
  * This is true for all known MIPS systems.
 #endif
 
 #ifndef cpu_has_mips_1
-# define cpu_has_mips_1                (!cpu_has_mips_r6)
+# define cpu_has_mips_1                (MIPS_ISA_REV < 6)
 #endif
 #ifndef cpu_has_mips_2
-# define cpu_has_mips_2                (cpu_data[0].isa_level & MIPS_CPU_ISA_II)
+# define cpu_has_mips_2                __isa_lt_and_flag(6, MIPS_CPU_ISA_II)
 #endif
 #ifndef cpu_has_mips_3
-# define cpu_has_mips_3                (cpu_data[0].isa_level & MIPS_CPU_ISA_III)
+# define cpu_has_mips_3                __isa_lt_and_flag(6, MIPS_CPU_ISA_III)
 #endif
 #ifndef cpu_has_mips_4
-# define cpu_has_mips_4                (cpu_data[0].isa_level & MIPS_CPU_ISA_IV)
+# define cpu_has_mips_4                __isa_lt_and_flag(6, MIPS_CPU_ISA_IV)
 #endif
 #ifndef cpu_has_mips_5
-# define cpu_has_mips_5                (cpu_data[0].isa_level & MIPS_CPU_ISA_V)
+# define cpu_has_mips_5                __isa_lt_and_flag(6, MIPS_CPU_ISA_V)
 #endif
 #ifndef cpu_has_mips32r1
-# define cpu_has_mips32r1      (cpu_data[0].isa_level & MIPS_CPU_ISA_M32R1)
+# define cpu_has_mips32r1      __isa_range_or_flag(1, 6, MIPS_CPU_ISA_M32R1)
 #endif
 #ifndef cpu_has_mips32r2
-# define cpu_has_mips32r2      (cpu_data[0].isa_level & MIPS_CPU_ISA_M32R2)
+# define cpu_has_mips32r2      __isa_range_or_flag(2, 6, MIPS_CPU_ISA_M32R2)
 #endif
 #ifndef cpu_has_mips32r6
-# define cpu_has_mips32r6      (cpu_data[0].isa_level & MIPS_CPU_ISA_M32R6)
+# define cpu_has_mips32r6      __isa_ge_or_flag(6, MIPS_CPU_ISA_M32R6)
 #endif
 #ifndef cpu_has_mips64r1
-# define cpu_has_mips64r1      (cpu_data[0].isa_level & MIPS_CPU_ISA_M64R1)
+# define cpu_has_mips64r1      __isa_range_or_flag(1, 6, MIPS_CPU_ISA_M64R1)
 #endif
 #ifndef cpu_has_mips64r2
-# define cpu_has_mips64r2      (cpu_data[0].isa_level & MIPS_CPU_ISA_M64R2)
+# define cpu_has_mips64r2      __isa_range_or_flag(2, 6, MIPS_CPU_ISA_M64R2)
 #endif
 #ifndef cpu_has_mips64r6
-# define cpu_has_mips64r6      (cpu_data[0].isa_level & MIPS_CPU_ISA_M64R6)
+# define cpu_has_mips64r6      __isa_ge_and_flag(6, MIPS_CPU_ISA_M64R6)
 #endif
 
 /*